標準クエリ演算子の概要
更新 : 2007 年 11 月
標準クエリ演算子は、統合言語クエリ (LINQ: Language-Integrated Query) パターンを形成するメソッドです。ほとんどの場合、そのメソッドの操作の対象はシーケンスです。シーケンスとは、IEnumerable<T> インターフェイスまたは IQueryable<T> インターフェイスを実装している型を持つオブジェクトのことです。標準クエリ演算子には、クエリ機能が用意されています。たとえば、フィルタ処理、射影、集計、並べ替えなどです。
2 組の LINQ 標準クエリ演算子があります。1 つは IEnumerable<T> 型のオブジェクトを操作するもので、もう 1 つは IQueryable<T> 型のオブジェクトを操作するものです。各組を構成するメソッドは、それぞれ Enumerable クラスと Queryable クラスの静的メンバです。それらは操作対象の型の拡張メソッドとして定義されています。これは、静的メソッド構文またはインスタンス メソッド構文を使用して呼び出すことができることを意味します。
また、標準クエリ演算子の複数のメソッドが、IEnumerable<T> または IQueryable<T> に基づく型以外の型を操作します。Enumerable 型は、2 つのメソッドを定義します。どちらも IEnumerable 型のオブジェクトを操作します。その 1 つは Cast<TResult>(IEnumerable) で、もう 1 つは OfType<TResult>(IEnumerable) というメソッドです。これらのメソッドを使用すると、パラメータ付きでない、または非ジェネリック型のコレクションを LINQ パターンでクエリできるようになります。これを行うには、厳密に型指定されたオブジェクトのコレクションを作成します。Queryable クラスは、類似した 2 つのメソッドを定義します。Cast<TResult>(IQueryable) と OfType<TResult>(IQueryable) です。これらは、Queryable 型のオブジェクトを操作します。
標準クエリ演算子の実行のタイミングは、シングルトン値を返すか、値のシーケンスを返すかで異なります。シングルトン値を返すメソッド (たとえば Average や Sum) は、直ちに実行されます。シーケンスを返すメソッドは、クエリの実行を遅延させ、列挙可能なオブジェクトを返します。
インメモリ コレクションを操作するメソッド、つまり、IEnumerable<T> を拡張するメソッドの場合、返される列挙可能なオブジェクトは、メソッドに渡された引数をキャプチャします。オブジェクトが列挙されると、クエリ演算子のロジックが使用され、クエリ結果が返されます。
一方、IQueryable<T> を拡張するメソッドはクエリ動作を実装しませんが、実行されるクエリを表す式ツリーをビルドします。クエリ処理は、ソース IQueryable<T> オブジェクトによって行われます。
クエリ メソッドの呼び出しは 1 回のクエリにまとめてチェインすることができます。これにより、クエリを複雑にすることができます。
標準クエリ演算子を使用してシーケンスに関する情報を取得する方法を次のコード例に示します。
Dim sentence As String = "the quick brown fox jumps over the lazy dog"
' Split the string into individual words to create a collection.
Dim words As String() = sentence.Split(" "c)
Dim query = From word In words _
Group word.ToUpper() By word.Length Into gr = Group _
Order By Length _
Select Length, GroupedWords = gr
Dim output As New System.Text.StringBuilder
For Each obj In query
output.AppendLine(String.Format("Words of length {0}:", obj.Length))
For Each word As String In obj.GroupedWords
output.AppendLine(word)
Next
Next
'Display the output
MsgBox(output.ToString())
' This code example produces the following output:
'
' Words of length 3:
' THE
' FOX
' THE
' DOG
' Words of length 4:
' OVER
' LAZY
' Words of length 5:
' QUICK
' BROWN
' JUMPS
string sentence = "the quick brown fox jumps over the lazy dog";
// Split the string into individual words to create a collection.
string[] words = sentence.Split(' ');
// Using query expression syntax.
var query = from word in words
group word.ToUpper() by word.Length into gr
orderby gr.Key
select new { Length = gr.Key, Words = gr };
// Using method-based query syntax.
var query2 = words.
GroupBy(w => w.Length, w => w.ToUpper()).
Select(g => new { Length = g.Key, Words = g }).
OrderBy(o => o.Length);
foreach (var obj in query)
{
Console.WriteLine("Words of length {0}:", obj.Length);
foreach (string word in obj.Words)
Console.WriteLine(word);
}
// This code example produces the following output:
//
// Words of length 3:
// THE
// FOX
// THE
// DOG
// Words of length 4:
// OVER
// LAZY
// Words of length 5:
// QUICK
// BROWN
// JUMPS
クエリ式の構文
頻繁に使用される標準クエリ演算子の中には、C# および Visual Basic 言語専用のキーワード構文を持つものがあります。そのような構文では、標準クエリ演算子をクエリ式の一部として呼び出すことができます。専用キーワードおよびそれに対応する構文を持つ標準クエリ演算子の詳細については、「標準クエリ演算子のクエリ式構文」を参照してください。
標準クエリ演算子の拡張
標準クエリ演算子の組を補強するには、対象のドメインまたはテクノロジに適したドメイン固有のメソッドを作成します。また、標準クエリ演算子を、リモート評価、クエリ変換、最適化などの追加のサービスが用意されている独自の実装で置き換えることもできます。例については、「AsEnumerable<TSource>」を参照してください。
関連項目
次のリンクは、機能別のさまざまな標準クエリ演算子についての追加情報を提供するトピックへのリンクです。