2014-01-13 6 views
3

Я только начинаю с F # и .Net, но после некоторого Googling я не нашел примеров этого. Приносим извинения заранее, если это слишком просто.Запрос базы данных Async

Я пытаюсь запросить базу данных и сделать это асинхронно. Например, у меня есть такая функция:

let queryExample name = 
    query {for f in foo do 
      where (f.name = name) 
      select f.name} 
    |> Seq.toList 

Теперь, как бы я сделал асинхронную версию этого? query не возвращает тип Async<'a>.

ответ

5

Ответ будет зависеть от того, что вы запрашиваете. Многие источники данных будут раскрывать что-то вроде контекста данных, который позволяет запускать запросы по-разному, но это не распространяется непосредственно на тип IQueryable (и, следовательно, это не то, что вы можете сделать непосредственно с результатом выражения query { ... }.

в качестве примера, если foo является LINQ к SQL Table<Foo>, то вы можете сделать что-то вроде этого:.

let queryExample name = 
    let q = 
     query { for f in foo do 
       where (f.name = name) 
       select f.name } 
    let cmd = foo.Context.GetCommand(q) 
    async { 
     let! reader = Async.AwaitTask (cmd.ExecuteReaderAsync()) 
     return foo.Context.Translate<Foo>(reader) 
    } 

Это вернет Async<seq<Foo>> Если вы будете работать много запросов, как это , тогда легко извлечь мясо этого в механизм многократного использования.

+0

Я использую LINQ-to-EF. В принципе, пока нет провайдера типов для PostgreSQL или MySQL, поэтому я должен использовать поставщика типов для структуры сущности. – siki

+1

@GaborSiklos - в случае EF это может быть намного проще (если вы используете EF 6). Я думаю, вы могли бы просто использовать метод расширения '' ToListAsync' (http://msdn.microsoft.com/en-us/library/dn220258 (v = vs.113) .aspx) в вашем запросе в сочетании с 'Async .AwaitTask'. – kvb

+0

Спасибо, но я использую EF 4.x. Какие у меня варианты? Спасибо за помощь! – siki

0

Пример ниже показывает простой синтаксис для этого. В основном просто создайте функцию async с выражением запроса внутри и верните результат.

let data = [ 1; 5; 7; 11; 18; 21] 

let getEvenInts = fun (arr : list<int>) -> async { 
    let q = query {   
     for N in arr do 
     where ((N % 2) = 0) 
     select N 
    } 
    return q 
    } 

let getOddInts = fun (arr : list<int>) -> async { 
    let q = query {   
     for N in arr do 
     where ((N % 2) <> 0) 
     select N 
    } 
    return q 
    } 

let evens = getEvenInts data |> Async.RunSynchronously 
let odds = getOddInts data |> Async.RunSynchronously 

printfn "Evens: %A Odds: %A" evens odds 
Смежные вопросы