Linq 如何使EF核心(2.1)编译查询返回IQueryable?

Linq 如何使EF核心(2.1)编译查询返回IQueryable?,linq,iqueryable,ef-core-2.1,Linq,Iqueryable,Ef Core 2.1,我一直在尝试将应用程序中经常执行的查询转换为编译查询,但没有成功。我把它归结为一个简单的问题,所以我得出结论,我一定是误解了某些东西是如何工作的 以下是不使用编译查询的简单查询示例(此示例有效): private static Func\u getUsers= (实体上下文)=> 从上下文中的au。用户选择au; 添加编译查询调用后: private static Func<Entities, int, string, IQueryable<Users>> _getUs

我一直在尝试将应用程序中经常执行的查询转换为编译查询,但没有成功。我把它归结为一个简单的问题,所以我得出结论,我一定是误解了某些东西是如何工作的

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

private static Func\u getUsers=
(实体上下文)=>
从上下文中的au。用户选择au;
添加编译查询调用后:

private static Func<Entities, int, string, IQueryable<Users>> _getUsers =
    EF.CompileQuery((Entities context) =>
        from au in context.Users select au);
private static Func\u getUsers=
EF.CompileQuery((实体上下文)=>
从上下文中的au。用户选择au);
我得到一个例外:

无法将类型“System.Func>”隐式转换为“System.Func>”。存在显式转换(是否缺少强制转换?)

就我而言,我不知道我做错了什么…有什么建议吗

如何使EF核心(2.1)编译查询返回IQueryable

你不能。所有
EF.Compile
方法返回
IEnumerable
TResult
,相应的
Async
方法分别返回
AsyncEnumerable
Task

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

我说不出确切的原因。EF核心文件中的解释如下:

尽管通常EF Core可以基于查询表达式的哈希表示自动编译和缓存查询,但该机制可以通过绕过哈希计算和缓存查找来获得较小的性能增益,允许应用程序通过调用委托来使用已编译的查询


看起来这样做的目的不仅是缓存
IQueryable
表达式树,还可以跳过表达式树到它们内部使用的任何数据结构的转换。

我认为这是有意义的。EF核心的编译步骤生成SQL。一旦你有了SQL语句,你就不能对它应用更多的可查询运算符,而不必将结果重新编译成SQL。@PanagiotisKanavos我不太确定它是SQL,特别是考虑到客户机/混合计算。但是可以肯定的是,对于查询的执行,有一些AST或类似的结构是特定的。谢谢。我很困惑,因为我看到一个例子,它的返回值是IQueryable。@jceddy这样做有什么好处吗?在互联网上有很多关于这方面的讨论。所以我有点困惑。虽然在某些情况下,它的执行速度比不使用外部编译时快,但在某些情况下,它的执行速度较慢。编译意味着创建SQL查询并重用它。对该查询应用更多LINQ运算符将意味着重新编译它。
private static Func<Entities, int, string, IQueryable<Users>> _getUsers =
    EF.CompileQuery((Entities context) =>
        from au in context.Users select au);