自定义 EF F# 查询转换器

问题描述 投票:0回答:1

在回答我的另一个问题时,我被告知使用

QueryExtensions
来通过 F# 和实体框架实现异步计算,并且我正在成功使用该建议。

例如我有以下功能:

let headAsync query =
    query
    |> QueryableExtensions.FirstAsync
    |> Async.AwaitTask

可以这样使用:

async {
    let! entity =
        query {
            for e in context.MyEntities do
            sortBy e.Id
        } |> headAsync
    return entity
}

使用我的新函数作为查询表达式会很好。我写过这个:

type QueryBuilderEx() =
    inherit Linq.QueryBuilder()

    [<CustomOperation("headAsync")>]
    member __.HeadAsync<'T, 'Q when 'Q :> System.Linq.IQueryable<'T>> (source: Linq.QuerySource<'T, 'Q>) : Async<'T> =
        let queryable = source.Source :?> 'Q
        queryable.FirstOrDefaultAsync() |> Async.AwaitTask

let query2 = QueryBuilderEx()

并尝试像这样使用它:

async {
    let! entity =
        query2 {
            for e in context.MyEntities do
            sortBy e.Id
            headAsync
        }
    return entity
}

这段代码编译得很好,但在运行时抛出以下异常:

System.NotSupportedException:这不是有效的查询表达式。方法 'Microsoft.FSharp.Control.FSharpAsync`1[Entities.MyEntity] HeadAsync[MyEntity,IQueryable`1](Microsoft.FSharp.Linq.QuerySource`2[Entities.MyEntity,System.Linq.IQueryable`1[Entities. MyEntity]])' 在查询中使用,但 F# 到 LINQ 查询转换器无法识别。检查允许查询的规范并考虑将某些操作移出查询表达式

那么,标准 LINQ 翻译器的扩展是否可能,或者我应该坚持以前的

headAsync
以普通函数的形式实现,而不弄乱
QueryBuilder

entity-framework linq f#
1个回答
0
投票

您可能会从拦截查询和即时重写中获得更多好处,您也许能够将表达式转换为 EF 翻译器可以使用的内容。请参阅https://github.com/ImaginaryDevelopment/IInterceptQueryables

© www.soinside.com 2019 - 2024. All rights reserved.