3

我想使用通用查询功能,例如:

let filter predicateFn =
    predicateFn |>
    fun f s -> query { for x in s do 
                       where (f(x)) 
                       select x }

其中 f 应该是谓词函数。显然,这不能转换为 sql 查询。但是有没有解决这个问题的方法。我已经看到了 C# 的示例解决方案。

方法取自:Daniel Mohl 的 F# 的 Web、云和移动解决方案。

编辑:示例以澄清:

let userSorter = fun (u:users) -> u.Login

let sorted  =
    query { for user in dbConn.GetDataContext().Users do 
                sortBy ((fun (u:users) -> u.Login)(user))
                select user.Login }

基本上,我想用 userSorter 替换 lambda。因为它是上面的代码运行,但这会失败:

let userSorter = fun (u:users) -> u.Login

let sorted  =
    query { for user in dbConn.GetDataContext().Users do 
                sortBy (userSorter(user))
                select user.Login }
4

1 回答 1

3

终于在 Stackoverflow 上找到了解决方案:

open System.Linq
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let runQuery (q:Expr<IQueryable<'T>>) = 
  match q with
  | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) ->
      query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body))
  | _ -> failwith "Wrong argument"

let test () =
  <@ query { for p in db.Products do
             where ((%predicate) p)
             select p.ProductName } @>
  |> runQuery
  |> Seq.iter (printfn "%s")

学分应该去 Tomas Petricek,你可以得到我的赏金!

编辑:匹配任何类型的查询结果'T查看我的其他问答

于 2013-06-05T21:55:15.243 回答