2014-01-13 132 views
3

我剛剛開始使用F#和.Net,但一些谷歌搜索後,我沒有找到這樣的例子。如果這太簡單,我很抱歉。異步數據庫查詢

我想查詢一個數據庫,並做到異步。例如,我有這樣的功能:

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

示例顯示了這樣一個簡單的語法。基本上只需創建一個帶有查詢表達式的異步函數並返回結果。

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