C# の LINQ クエリ構文とメソッド構文
LINQ には2つの書き方がある。クエリ構文とメソッド構文だ。どちらも同じ結果を得られるが、見た目と使い勝手が異なる。
クエリ構文
SQL に似た書き方で、宣言的にクエリを記述する。
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var query = from n in numbers
where n % 2 == 0
orderby n descending
select n;
foreach (var n in query)
{
Console.WriteLine(n); // 10, 8, 6, 4, 2
}from、where、orderby、select といったキーワードを使う。SQL を知っている人には馴染みやすい構文である。
メソッド構文
拡張メソッドをチェーンして記述する。ラムダ式と組み合わせて使う。
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var query = numbers
.Where(n => n % 2 == 0)
.OrderByDescending(n => n);
foreach (var n in query)
{
Console.WriteLine(n); // 10, 8, 6, 4, 2
}メソッドをドットで繋げていく。各メソッドが何をしているか、コードから直接読み取れる。
両者の比較
クエリ構文
SQL ライクで直感的。複雑な結合やグループ化が読みやすい。ただし使えるメソッドに制限がある。
メソッド構文
すべての LINQ メソッドが使える。短いクエリでは簡潔に書ける。慣れると可読性も高い。
実際のところ、クエリ構文はコンパイル時にメソッド構文に変換される。つまり両者は等価であり、好みや状況に応じて使い分ければよい。
クエリ構文でできないこと
一部の LINQ メソッドはクエリ構文では直接呼び出せない。
int[] numbers = { 1, 2, 3, 4, 5 };
// メソッド構文でしか使えない例
int count = numbers.Count();
int sum = numbers.Sum();
int first = numbers.First();
bool any = numbers.Any(n => n > 3);Count、Sum、First、Any などの集計・判定メソッドはメソッド構文で呼び出す必要がある。クエリ構文と組み合わせる場合は、クエリを括弧で囲んでからメソッドを呼ぶ。
int[] numbers = { 1, 2, 3, 4, 5 };
int count = (from n in numbers
where n > 2
select n).Count();
Console.WriteLine(count); // 3どちらを使うべきか
現場ではメソッド構文が主流だ。理由はいくつかある。
ただし、複数のデータソースを結合するような複雑なクエリでは、クエリ構文の方が読みやすいこともある。両方の書き方を理解しておき、状況に応じて選択するのが理想的だ。