【问题标题】:query function with predicate带谓词的查询函数
【发布时间】:2011-05-24 13:59:14
【问题描述】:

Mjello 在那里!我目前正在尝试创建一个 F# 应用程序,但现在我遇到了另一面墙。

问题在于Microsoft.FSharp.Linq.Query 模块,如果它们作为参数传递,那里的query 函数不会接受我的谓词。看看这个:

member x.GetUsersWhere (e:User -> bool) =
    query <@ ctx.Users |> Seq.filter e @>

然后我这样称呼它:

let service = new UserService()
service.GetUsersWhere (fun z -> z.Name = "James")

应该没问题吧?好吧,编译器同意:

以下构造用于 查询但不被识别 F# 到 LINQ 查询转换器:调用 (没有任何, System.Collections.Generic.IEnumerable1[WebFSharp.Entities.User] op_PipeRight[DbSet1,IEnumerable1](System.Data.Entity.DbSet1[WebFSharp.Entities.User], Microsoft.FSharp.Core.FSharpFunc2[System.Data.Entity.DbSet1[WebFSharp.Entities.User],System.Collections.Generic.IEnumerable1[WebFSharp.Entities.User]]), [PropertyGet (Some (FieldGet (Some (Value (WebFSharp.Business.UserService)), WebFSharp.Business.MyContext ctx)), System.Data.Entity.DbSet1[WebFSharp.Entities.User] 用户, []), 让(谓词,值(), 拉姆达(来源, 呼叫(无, System.Collections.Generic.IEnumerable1[WebFSharp.Entities.User] Filter[User](Microsoft.FSharp.Core.FSharpFunc2[WebFSharp.Entities.User,System.Boolean], System.Collections.Generic.IEnumerable1[WebFSharp.Entities.User]), [predicate, Coerce (source, System.Collections.Generic.IEnumerable1[[WebFSharp.Entities.User, WebFSharp.Entities,版本=0.0.0.0, 文化=中性, PublicKeyToken=null]])])))]) 这是 不是有效的查询表达式。查看 允许查询的规范 并考虑移动一些查询 超出报价范围

发生了什么事?是不是因为Expr会在参数注入之前被求值?

不管怎样,下面的代码可以工作,但灵活性要差得多:

member x.GetUsersByName name =
    query <@ ctx.Users |> Seq.filter(fun z -> z.Name = name) @>

let service = new UserService()
service.GetUsersByName "James"

有人能解释一下发生了什么吗?

【问题讨论】:

    标签: f#


    【解决方案1】:

    在您的代码中,F# to LINQ 转换器无法检查您指定的函数(参数e 是一些已编译的代码 - 无法获取可以转换为的引用表示SQL)。

    您需要使用Expr&lt;User -&gt; bool&gt; 而不是User -&gt; bool。这意味着您将传递用作参数的代码的一些表示形式(可以分析并转换为 SQL),而不是传递函数:

    member x.GetUsersWhere (e:Expr<User -> bool>) = 
        query <@ ctx.Users |> Seq.filter %e @>
    

    注意%e 语法 - 这意味着引用的代码应该嵌入(拼接)到主要的引用表达式中,因此翻译器将其视为单个表达式。在调用它时,您也需要使用引号传递函数:

    let service = new UserService()service.GetUsersWhere <@ fun z -> z.Name = "James" @>
    

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      相关资源
      最近更新 更多