LINQ (および LINQ to XML) の最も重要な利点の 1 つは、チェーンされたクエリが、チェーンされたクエリよりも大きく複雑な 1 つのクエリと同様に実行できることです。
チェーン クエリは、別のクエリをソースとして使用するクエリです。 たとえば、次の単純なコードでは、 query2
のソースとして query1
があります。
XElement root = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Child", 3),
new XElement("Child", 4)
);
var query1 = from x in root.Elements("Child")
where (int)x >= 3
select x;
var query2 = from e in query1
where (int)e % 2 == 0
select e;
foreach (var i in query2)
Console.WriteLine("{0}", (int)i);
Dim root As New XElement("Root", New XElement("Child", 1), New XElement("Child", 2), New XElement("Child", 3), New XElement("Child", 4))
Dim query1 = From x In root.Elements("Child") Where CInt(x) >= 3x
Dim query2 = From e In query1 Where CInt(e) Mod 2 = 0e
For Each i As var In query2
Console.WriteLine("{0}", CInt(i))
Next
この例では、次の出力が生成されます。
4
このチェーン クエリは、リンクされたリストを反復処理する場合と同じパフォーマンス プロファイルを提供します。
- Elements軸のパフォーマンスは、リンクリストを反復処理する場合と基本的に同じです。 Elements は、遅延実行を持つ反復子として実装されます。 これは、反復子オブジェクトの割り当てや実行状態の追跡など、リンクされたリストの反復処理に加えて、いくつかの作業を実行することを意味します。 この作業は、反復子の設定時に実行される作業と、各イテレーション中に実行される作業の 2 つのカテゴリに分けることができます。 セットアップ作業は少量の固定作業であり、各イテレーション中に実行される作業は、ソース コレクション内の項目の数に比例します。
query1
では、where
句 (Visual Basic のWhere
) により、クエリによって Where メソッドが呼び出されます。 このメソッドは反復子としても実装されます。 セットアップ作業は、ラムダ式を参照するデリゲートのインスタンス化と、反復子の通常のセットアップで構成されます。 反復処理のたびに、デリゲートが呼び出されて条件が実行されます。 各イテレーションの間に行われるセットアップ作業と作業は、軸の反復処理中に実行される作業と似ています。query1
では、select 句によってクエリが Select メソッドを呼び出します。 このメソッドのパフォーマンス プロファイルは、 Where メソッドと同じです。query2
では、where
句 (Visual Basic のWhere
) とselect
句の両方に、query1
と同じパフォーマンス プロファイルがあります。
したがって、 query2
を通じた反復は、最初のクエリのソース内の項目数 (つまり、線形時間) に直接比例します。
反復子の詳細については、「 yield」を参照してください。
クエリの連結に関するより詳細なチュートリアルについては、「 チュートリアル: クエリを連結する (C#)」を参照してください。
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET