在对my another question的回答中,我被告知要使用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:这不是有效的查询表达式。方法&#39; Microsoft.FSharp.Control.FSharpAsync`1 [Entities.MyEntity] HeadAsync [MyEntity,IQueryable`1](Microsoft.FSharp.Linq.QuerySource`2 [Entities.MyEntity,System.Linq.IQueryable`1 [Entities.MyEntity]])&#39;在查询中使用但F#-to-LINQ查询转换器无法识别。检查允许的查询的规范,并考虑将一些操作移出查询表达式
那么,标准LINQ翻译器的扩展是否可行,或者我应该以普通函数的形式坚持我以前的headAsync
实现而不会弄乱QueryBuilder
?