如何使 EF-Core (2.1) 编译查询 return 成为 IQueryable?

How do I make an EF-Core (2.1) Compiled Query return an IQueryable?

我一直在尝试将在我的应用程序中经常执行的查询转换为编译查询,但没有成功。我已将其归结为一个简单的查询,因此得出结论,我一定是误解了某些东西的工作原理。

这是不使用编译查询的简单示例查询(有效):

private static Func<Entities, int, string, IQueryable<Users>> _getUsers =
    (Entities context) =>
        from au in context.Users select au;

添加编译查询调用后:

private static Func<Entities, int, string, IQueryable<Users>> _getUsers =
    EF.CompileQuery((Entities context) =>
        from au in context.Users select au);

我得到这个异常:

Cannot implicitly convert type 'System.Func>' to 'System.Func>'. An explicit conversion exists (are you missing a cast?)

对于我的生活,我无法弄清楚我做错了什么......有什么建议吗?

How do I make an EF-Core (2.1) Compiled Query return an IQueryable?

你不能。所有 EF.Compile 方法 return IEnumerable<TResult>TResult,相应的 Async 方法 return 分别为 AsyncEnumerable<TResult>Task<TResult>.

如您所见,没有 IQueryable<T> returning 方法。换句话说,编译后的查询应该是最终的(不可组合的)——重载允许您传递必要的参数。

我不能确切地说出这是为什么。 EF Core文档中对Explicitly Compiled Queries的解释是:

Although in general EF Core can automatically compile and cache queries based on a hashed representation of the query expressions, this mechanism can be used to obtain a small performance gain by bypassing the computation of the hash and the cache lookup, allowing the application to use an already compiled query through the invocation of a delegate.

看起来这个想法不仅要缓存 IQueryable 表达式树,还要跳过表达式树到它们内部使用的任何数据结构的转换。

只能return IEnumerable类型,但可以用AsQueryable触发。