【问题标题】:Linq Include helper function for f# style pipeliningLinq 包含用于 f# 样式流水线的辅助函数
【发布时间】:2013-05-11 19:26:27
【问题描述】:

我想从数据库中急切地加载一些记录及其关系,如下所示:

let getEmails() =
    let emails =
        (query { for q in entities.QueueItems do
                    select q.Email
                    take batchSize }
        ).Include(fun (e:Email) -> e.QueueItem)
        |> Seq.toArray

    emails 
    |> Array.iter (fun e -> entities.QueueItems.Remove(e.QueueItem) |> ignore)

    entities.SaveChanges(logger) |> ignore 
    emails

这很好用,尽管我必须将查询表达式括在括号中才能调用 include,这看起来有点奇怪。我想知道是否可以编写一个辅助函数来以更惯用的 F# 样式调用 Include,我想出了这个。

module Ef =
    let Include (f:'a -> 'b) (source:IQueryable<'a>) = 
        source.Include(f)

现在我的查询看起来像这样(类型推断适用于可查询类型:D)

let emails =
    query { for q in entities.QueueItems do
                select q.Email
                take batchSize }
    |> Ef.Include(fun e -> e.QueueItem)
    |> Seq.toArray

它编译!但是当我运行它时,我从 DbExtensions 库中得到一个错误,告诉我The Include path expression must refer to a navigation property defined on the type.

在传递给 Queryable.Include 之前检查 lambda 函数,它看起来像这样{&lt;StartupCode$Service&gt;.$Worker.emails@30} Microsoft.FSharp.Core.FSharpFunc&lt;Entities.Email,Entities.QueueItem&gt; {&lt;StartupCode$Service&gt;.$Worker.emails@30}

我想问题在于我的 lambda 是如何被解释的,以及FSharpFuncs 和Expression&lt;Func&lt;&gt;&gt;s 之间的转换。我尝试重写我的辅助函数,使其具有Expression&lt;Func&lt;'a, 'b&gt;&gt; 作为其第一个参数,甚至下载了 FSharp.Core 源代码以在 Seq 模块和 QueryBuilder 的实现中寻找灵感,但我无法得到任何工作。我尝试重新定义我的辅助函数:

module Ef =
    let Include (y:Expression<Func<'a,'b>>) (source:IQueryable<'a>) = 
        source.Include(y)

然后我得到编译器错误This function takes too many arguments, or is used in a context where a function is not expected

我有点难过。任何人都可以建议我如何使它工作吗?

【问题讨论】:

    标签: entity-framework f# ef-code-first pipelining query-expressions


    【解决方案1】:

    AFAIR 类型导向的转换仅适用于非柯里化类型成员,不适用于 let 绑定。 作为修复,您可以尝试将 Ef.Include 更改为静态成员

    type Ef = 
        static member Include (f : Expression<System.Func<'a, 'b>>) = 
            fun (q : IQueryable<'a>)  -> q.Include f
    

    【讨论】:

    • 很好的解决方案!时间去阅读类型导向的转换。非常感谢。
    猜你喜欢
    • 2016-04-02
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2022-10-20
    • 2022-01-21
    • 2022-01-05
    相关资源
    最近更新 更多