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;
    ...
}

必要に応じて結果を1つずつ取得します。この「怠惰」/「ストリーミング」の考え方は、クエリ全体で機能します。Select は必要に応じて OrderBy を呼び出し、必要に応じて Where を呼び出し、必要に応じて Collection を呼び出します。

1 つの奇妙な点は、「OrderBy」です。これは、実装上の理由から、必要なすべての結果を順序付けする前に取得し、結果をストリーミングする場合があります。この取得は、最初に呼び出されたときに行われます。

于 2012-08-25T01:19:27.663 に答える
1

クエリは foreach の前に実行されません。foreach ループの各反復は、クエリから 1 つの結果を返します。

完全に実体化されたデータの結果セットは存在しないため、大きすぎることもありません。

LINQ クエリは実行を延期します。反復すると、指定した述語と射影を適用して、データを前方に「スライド」します。

于 2012-08-25T01:16:29.253 に答える