【问题标题】:How do I make an EF-Core (2.1) Compiled Query return an IQueryable?如何使 EF-Core (2.1) 编译查询返回 IQueryable?
【发布时间】:2019-04-28 07:08:37
【问题描述】:

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

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

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);

我得到了这个例外:

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

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

【问题讨论】:

  • 编译意味着创建 SQL 查询并重用它。将 more LINQ 运算符应用于该查询将意味着 重新编译它。

标签: linq iqueryable ef-core-2.1


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如何使 EF-Core (2.1) 编译查询返回 IQueryable?

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

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

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

    虽然通常 EF Core 可以根据查询表达式的哈希表示自动编译和缓存查询,但这种机制可以通过绕过哈希计算和缓存查找来获得小的性能增益,允许应用程序通过委托调用使用已编译的查询。

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

    【讨论】:

    • 我认为这是有道理的。 EF Core 的编译步骤生成 SQL。一旦你有了那个 SQL 语句,你就不能对它应用更多的 Queryable 运算符,而不必重新将结果编译成 SQL。
    • @PanagiotisKanavos 我不太确定是 SQL,尤其是考虑到客户端/混合评估。但可以肯定的是,某些 AST 或类似的结构特定于查询的执行。
    • 谢谢。我很困惑,因为我看到了一个以 IQueryable 作为返回值的示例。
    • @jceddy 你这样做有什么好处吗?网上有很多关于这个的讨论。所以这让我有点困惑。虽然在某些情况下它的执行速度比没有外部编译的情况下要快,但在某些情况下它的速度较慢。
    猜你喜欢
    • 2015-09-21
    • 2020-03-29
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2023-01-03
    • 1970-01-01
    相关资源
    最近更新 更多