1

假设我们有以下 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 循环时,查询指定的数据似乎已经被查询出来。那么这个查询动作是什么时候发生的呢?是在我定义 LINQ 查询对象的时候IEnumerable<Customer> 吗?

  • 如果数据量太大,有没有后期查询 机制?(我不确定描述这一点的正确词,但我希望你能理解我。)

4

3 回答 3

5

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

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

于 2012-08-25T01:11:56.010 回答
3

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

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

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

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

于 2012-08-25T01:19:27.663 回答
1

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

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

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

于 2012-08-25T01:16:29.253 回答