【问题标题】:When is the LINQ query actually get executed?LINQ 查询何时真正执行?
【发布时间】:2012-08-26 11:48:58
【问题描述】:

假设我们有以下 LINQ 查询:

var query =
    from    c in Customers
    where   c.Country == "Italy"
    orderby c.Name
    select  new { c.Name, c.City };

编译器会这样转换:

IEnumerable<Customer> query =
        Customers
        .Where( c => c.Country == "Italy" );
        .OrderBy( c => c.Name )
        .Select( c => new { c.Name, c.City } );

然后我可以使用这样的查询:

foreach ( var name_city_pair in query ) ...

问题是:

  • 查询指定的数据好像已经被查询出来了 当我使用 foreach 循环时。那么这个查询动作是什么时候发生的呢? 当我定义IEnumerable&lt;Customer&gt;的LINQ查询对象时 ?

  • 如果数据量太大,是否有延迟查询 机制? (我不确定描述这个的正确词,但是 我希望你能得到我。)

【问题讨论】:

  • 我想你上面可能有一些语法错误。您正在选择 Anonymous 类型,然后说所选对象的类型为 Customer,然后像 IEnumerable. 一样遍历查询
  • 感谢您的提醒。现已更正。

标签: linq


【解决方案1】:

LINQ 尽可能使用延迟执行。在您的示例中,查询仅在您遍历结果时执行。

To 开头的方法(如ToList)会导致立即执行查询。还有一些返回单个值的方法,例如Count,会导致查询立即执行。

【讨论】:

    【解决方案2】:

    一般来说,LINQ 会尽可能地懒惰。例如,您希望它在幕后看起来像这样:

    foreach ( string name in query ) ...
    //Roughly translates into
    while (query.MoveNext())
    {
        string name = query.Current;
        ...
    }
    

    它只在需要时得到结果,一一获得。这种“惰性”/“流式”思维贯穿整个查询 - Select 根据需要调用 OrderBy,根据需要调用 Where,根据需要调用 Collection。

    一个奇怪的是“OrderBy”,出于实现原因,它可能会在排序之前检索所有需要的结果,然后流式传输结果。此检索将在第一次调用时发生。

    【讨论】:

    • 这是否假设 Linq-To-Objects?如果是这样,如果是 Linq-To-Sql 或实体框架,你的答案会有所不同吗?
    • 细节假设 LinqToObjects,尽管所有实现都应该尝试惰性 IIRC。例如,MongoDB 将在第一次调用时编译并发送查询到数据库,并返回一个“MongoCursor”,它将处理每次迭代 IIRC 的文档获取。 [它可以一次批处理文件 4MB IIRC]。
    【解决方案3】:

    查询不会在 foreach 之前执行。 foreach 循环中的每次迭代都会从您的查询中返回一个结果。

    从来没有完全具体化的数据结果集,所以也不能太大。

    LINQ 查询延迟执行。当您进行迭代时,它将应用您指定的谓词和预测在您的数据上“滑动”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2011-11-09
      • 1970-01-01
      相关资源
      最近更新 更多