gpt4 book ai didi

c# - Linq2Entities CompiledQuery 用于使用连接的查询

转载 作者:行者123 更新时间:2023-11-30 18:39:24 26 4
gpt4 key购买 nike

我有一个查询执行得不太好,例如生成的 SQL 代码是次优的。

原始语句看起来像这样(简化):

ctx.Table1.Where(t => ...)
.OrderBy(t => ....)
.Select(t => new {Table1 = t,
SomeProperty = t.Table2.SomeProperty,
SomeProperty2 = t.Table2.SomeProperty2,
AnotherProperty = t.Table3.AnotherProperty,
...
}

我查看了 SQL Profiler,发现生成的 SQL 会多次连接同一个表,并且该语句将花费大约 1 秒的时间来执行。

然后我将语句重写为以下几行:

from t in ctx.Table1
join t2 in ctx.Table2 on t.key equals t2.key into lt2
from t2 in lt2.DefaultIfEmpty()
join t3 in ctx.Table3 on t.key equals t3.key into lt3
from t3 in lt3.DefaultIfEmpty()
where t ...
orderby t...
select new {Table1 = t, .... }

这生成了一个更好的语句,当从 SQL 探查器中抓取并在 Management Studio 中执行时,它的速度是上一个示例中代码生成的语句的两倍。

但是,当运行第二个示例中的代码时,EF 生成表达式所花费的时间远远超过了从查询优化中获得的时间。

那么我该如何将第二条语句写成 CompiledQuery。我基本上不知道如何从 CompiledQuery 返回匿名类型。

最佳答案

我发现使用 CompiledQueries 的解决方法是:

  1. 在每个使用 LINQ to Entity 的 QueryX() 方法之前添加一个私有(private) InitQueryX() 方法。
  2. 使用属性和反射从 Init() 方法调用所有 InitQueryX() 方法。
  3. 在应用程序启动时调用 Init() 方法一次。

这会在开始时强制编译查询,但能够以比 CompiledQueries 更灵活的方式编写查询。

InitQueryX() 应该使用多个虚拟输入,以便它覆盖 QueryX() 方法中的所有路径(有点像单元测试代码覆盖率)。

如果可能,InitQueryX() 的输入应该是在数据库中产生 0 行的模拟,这样 Init() 方法将花费更少的时间来运行。

关于c# - Linq2Entities CompiledQuery 用于使用连接的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9907870/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com