2014-01-13 84 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