方法 : C# で LINQ クエリを作成する
このトピックでは、C# で LINQ クエリを作成する次の 3 つの方法について説明します。
クエリ構文を使用する。
メソッド構文を使用する。
クエリ構文とメソッド構文を組み合わせて使用する。
上に示したそれぞれの方法を使用した簡単な LINQ クエリを以下の例に示します。一般に、クエリを作成する規則として、可能な限り (1) を使用し、必要に応じて (2) および (3) を使用します。
[!メモ]
これらのクエリは、簡単なメモリ内コレクションで動作します。ただし、基本的な構文は、LINQ to SQL および LINQ to XML で使用される構文と同じです。
使用例
クエリ構文
ほとんどのクエリを作成する場合に、クエリ構文を使用してクエリ式を作成する方法が推奨されます。次の例では、3 つのクエリ式を示します。最初のクエリ式は、where 句を使用した条件を適用することにより、結果をフィルター処理または制限する方法を示しています。これは、ソース シーケンス内の値が 7 よりも大きいか 3 よりも小さいすべての要素を返します。2 番目の式は、返された結果の順序を指定する方法を示します。3 番目の式は、結果をキーに従ってグループ化する方法を示します。このクエリは、単語の最初の文字に基づいて 2 つのグループを返します。
// Query #1.
List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// The query variable can also be implicitly typed by using var
IEnumerable<int> filteringQuery =
from num in numbers
where num < 3 || num > 7
select num;
// Query #2.
IEnumerable<int> orderingQuery =
from num in numbers
where num < 3 || num > 7
orderby num ascending
select num;
// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable<IGrouping<char, string>> queryFoodGroups =
from item in groupingQuery
group item by item[0];
このクエリの型は IEnumerable<T> です。次の例に示すように、これらのクエリのすべてを var を使用して記述できます。
var query = from num in numbers...
前のそれぞれの例で、foreach ステートメントによるクエリ変数の反復処理が完了するまで、クエリは実行されません。詳細については、「LINQ クエリの概要 (C#)」を参照してください。
メソッド構文
一部のクエリ操作は、メソッド呼び出しとして表現する必要があります。最も一般的なメソッドは、Sum、Max、Min、Average など、シングルトン数値を返すメソッドです。これらのメソッドは単一の値のみを表し、追加のクエリ操作のソースとして使用できないため、いずれのクエリでも常に最後に呼び出す必要があります。クエリ式のメソッド呼び出しの例を次に示します。
List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
// Query #4.
double average = numbers1.Average();
// Query #5.
IEnumerable<int> concatenationQuery = numbers1.Concat(numbers2);
メソッドにパラメーターがある場合は、次の例に示すように、ラムダ式の形式で渡します。
// Query #6.
IEnumerable<int> largeNumbersQuery = numbers2.Where(c => c > 15);
前のクエリでは、Query #4 だけがすぐに実行されます。これは、IEnumerable<T> ジェネリック コレクションではなく、単一の値が返されるためです。メソッド自体は、値を計算するために foreach を使用する必要があります。
前の各クエリは、次の例に示すように、var による暗黙の型指定を使用して記述できます。
// var is used for convenience in these queries
var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);
クエリ構文とメソッド構文の組み合わせ
この例では、クエリ句の結果に基づいてメソッド構文を使用する方法を示します。クエリ式をかっこで囲み、ドット演算子を適用してメソッドを呼び出します。次の例で Query #7 は、値が 3 ~ 7 の数を返します。ただし、通常は、2 番目の変数を使用してメソッド呼び出しの結果を格納することをお勧めします。この方法では、クエリがクエリの結果と混同される可能性が低くなります。
// Query #7.
// Using a query expression with method syntax
int numCount1 =
(from num in numbers1
where num < 3 || num > 7
select num).Count();
// Better: Create a new variable to store
// the method call result
IEnumerable<int> numbersQuery =
from num in numbers1
where num < 3 || num > 7
select num;
int numCount2 = numbersQuery.Count();
Query #7 は、ジェネリック コレクションではなく単一の値を返すため、すぐに実行されます。
前の各クエリは、次に示すように、var による暗黙の型指定を使用して記述できます。
var numCount = (from num in numbers...
メソッド構文では次のように記述できます。
var numCount = numbers.Where(n => n < 3 || n > 7).Count();
明示的な型指定を使用すると、次のように記述できます。
int numCount = numbers.Where(n => n < 3 || n > 7).Count();