Mjello在那里!我正在尝试创建一个F#应用程序,现在我已经打了另一面墙.
问题出现在Microsoft.FSharp.Linq.Query模块中,query如果它们作为参数传递,那里的函数就不会接受我的谓词.看一下这个:
member x.GetUsersWhere (e:User -> bool) =
query <@ ctx.Users |> Seq.filter e @>
Run Code Online (Sandbox Code Playgroud)
然后我称之为:
let service = new UserService()
service.GetUsersWhere (fun z -> z.Name = "James")
Run Code Online (Sandbox Code Playgroud)
那应该没问题呃?好吧,编译器同意:
在查询中使用了以下构造,但F#-to-LINQ查询转换器无法识别:Call(None,System.Collections.Generic.IEnumerable
1[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] Users,[]),Let(predicate,Value(),Lambda(source,Call(None,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,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null ]])])))])这不是一个有效的查询表达式.检查允许查询的规范,并考虑将部分查询移出报价
这是怎么回事?是因为在Expr将参数注入到它之前会对它进行评估吗?
无论如何,以下代码有效,但灵活性要低得多:
member x.GetUsersByName name =
query <@ ctx.Users |> Seq.filter(fun z -> z.Name = name) @>
let service = new UserService()
service.GetUsersByName "James"
Run Code Online (Sandbox Code Playgroud)
有谁可以请谈谈发生了什么?
在您的代码中,F#到LINQ转换器没有任何方法来检查您指定的函数(参数e是一些已编译的代码 - 没有办法获得可以转换为SQL的引用表示).
你需要使用Expr<User -> bool>而不是User -> bool.这意味着您不会传递函数,而是传递一些用作参数的代码(可以分析并转换为SQL):
member x.GetUsersWhere (e:Expr<User -> bool>) =
query <@ ctx.Users |> Seq.filter %e @>
Run Code Online (Sandbox Code Playgroud)
注意%e语法 - 这意味着引用的代码应该嵌入(拼接)到主引用表达式中,因此翻译者将其视为单个表达式.调用它时,您还需要使用引号传递函数:
let service = new UserService()service.GetUsersWhere <@ fun z -> z.Name = "James" @>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1308 次 |
| 最近记录: |