【问题标题】:When does a compiled query that returns an IQueryable execute?返回 IQueryable 的已编译查询何时执行?
【发布时间】:2009-09-18 15:52:28
【问题描述】:

好的,我需要在这里进行健全性检查...

我编译了一个在执行时返回 IQueryable 的查询。

在以下示例中,查询应在哪一行实际对数据库执行?

101 IQueryable<T> results = MyCompiledQuery(MyDataContext);
102 List<T> final = (from t in result
103                  where t.ID > 5
104                  select t).ToList<T>();

这是我如何定义编译后的查询

 public static Func<MyDataContext, IQueryable<Widget>> MyCompiledQuery=
        CompiledQuery.Compile<MyDataContext, IQueryable<Widget>>(
                      (MyDataContext db) =>
                      from w in db.Widgets
                      where ((w.Type == WidgetType.Atype ||  //Widget.Atype is a Linq to Sql object, that I've defined statically
                              w.Type == WidgetType.Btype ||  //See above comment
                              w.Type == WidgetType.Ctype ) && //See above comment
                              w.Location == WidgetLocation.Domestic)  //Samething applies here
                        select euc);

更多讨论请参考: LINQ to SQL compiled queries and when they execute

【问题讨论】:

    标签: c# .net linq-to-sql


    【解决方案1】:

    它在第 104 行执行(当您调用 ToList() 时)。

    编译查询是在编译时只翻译一次到 TSQL 的查询,而不是每次在执行之前。

    【讨论】:

    • 你是对的,但你是在分裂头发。 ToList 在第 104 行,而不是第 102 行。这不是一个棘手的问题,他想知道编译查询是否意味着它立即执行,而不是 3 行中的哪一行是语句。
    • 我想它在 102/104 处执行,但是当我运行调试器和 SQL Profiler 时,我看到一条 SQL 语句在 101 执行后运行,然后是 12 个 SQL 语句(每个执行一个101 的结果)以 102/104 运行
    • @Antilogic:这取决于您如何编写已编译的查询,对吧?如果不能延迟,则立即执行。
    • @Alan,查看原始帖子我已对其进行了更新以包含我编译的查询的示例。
    • @Antilogic 在调试器中逐个执行语句时可以看到这种行为。在没有断点的情况下运行这两个语句,看看发出了多少 SQL 语句。
    【解决方案2】:

    此查询在第 101 行执行。我通过执行 SQL Profiler 跟踪对其进行了验证。我猜这是因为它是一个编译查询。

    你正在做的过滤后记> 5是在内存中完成的。

    【讨论】:

    • -1 再次检查跟踪。如果需要有关数据库结构的信息,可能会有一些流量,但实际查询不是通过编译来执行的。例如,此页面明确指出您可以在编译查询后提供参数值,如果还执行了查询,则无法提供:msdn.microsoft.com/en-us/library/bb896297.aspx
    • 调用编译后的查询方法会导致查询在数据库上运行。我已经用一个简单的数据库多次检查过它。当然你可以传递参数值,我不是说编译会导致它执行,我是说调用编译后的查询方法会导致它执行,而不是 .ToList() 方法。
    【解决方案3】:

    “在第104行,做ToList转换时。”

    嗯,这个答案是不正确的。我们在第 101 行调用存储在 MyCompiledQuery 变量中的委托,它返回编译查询的结果,而不是查询本身。

    【讨论】:

    • 我认为这个查询实际上是在第 101 行执行的(甚至在调用 ToList 之前)。
    • 没有。第 101 行创建查询。获取实际数据时执行查询。
    • 不是在编译查询的情况下,通过linq 2 sql provider source code检查。对于已编译的查询,它在第 101 行命中。stackoverflow.com/questions/6592386/…
    • 问题是“查询实际上对数据库执行”而不是在执行委托时。
    • @彼得。这个委托创建并执行查询。最初我认为它只是创建一个。我错了。
    【解决方案4】:

    这称为延迟执行。
    你可以阅读一篇关于它的好帖子here

    【讨论】:

    • 是的,这就是我的想法,也是我设计应用程序的方式。但是,当应用程序执行第 101 行时,我在 SQL Profiler 中看到一条 SQL 语句飞过,然后是第 101 行返回的每个结果的另一个 SQL 语句。
    • 我可以确认 Antilogic 发布的内容。查询在第 101 行执行
    • @Antilogic:编译查询的过程可能需要有关数据库结构的信息,但在那个阶段它不会获取任何数据。如果是这样,那么稍后在您使用结果时它不会获取任何内容。
    【解决方案5】:

    据我所知,IQueryable 永远不会被执行,它只是将 Linq 查询转换为可查询的格式,以便在请求时执行。

    在这种情况下,我猜当它被要求转换为 List 时,它会查询结果。 102 和 104 行没有意义,因为它们都代表一条线。

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 2019-04-28
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多