基本的なLINQ（クエリ構文）

# はじめに

https://qiita.com/masayasu_t/items/1cdad910d38a872b836e

(私の中で)使うことが多い「メソッド構文」については上記に書きました。
相変わらず「メソッド構文」ばかり使っていたのですが、少々「クエリ構文」をかじってみました。

出来ることは変わりませんが、状況によって書きやすさに差があると感じたので纏めてみました。


### 存在チェック(Any)
```c#:C#
// x.kind == 3が存在するか
// メソッド構文
bool vegetableAnyM = m_vegetable.Any(x => x.kind == 3);
// クエリ構文
bool vegetableAnyQ = (from x in m_vegetable
                      where x.kind == 3
                      select x).Any();
```
メソッド構文で書いたほうがシンプル

### 件数取得(Count)
```c#:C#
// x.kind == 2が何個あるか
// メソッド構文
int vegetableCountM = m_vegetable.Count(x => x.kind == 2);

// x.kind毎に何個あるか
// クエリ構文
var vegetableCountQ = from x in m_vegetable
                      group x by x.kind into g
                      select new { kind = g.Key, count = g.Count()};
```
メソッド構文は、条件指定の件数を取りやすい
クエリ構文は、グループ集計がしやすい

### 並び替え(OrderBy)
```c#:C#
// x.idの昇順に並び替え
// メソッド構文
var vegetableOrderByM = m_vegetable.OrderBy(x => x.id);
// クエリ構文
var vegetableOrderByQ = from x in m_vegetable
                        orderby x.id
                        select x;

// x.idの降順に並び替え
// メソッド構文
var vegetableOrderByDescendingM = m_vegetable.OrderByDescending(x => x.id);
// クエリ構文
var vegetableOrderByDescendingQ = from x in m_vegetable
                                  orderby x.id descending
                                  select x;

```
並び変えるだけなら、メソッド構文で書いたほうがシンプル

### 絞り込み(Where)
```c#:C#
// x.kind == 1のデータを絞り込み
// メソッド構文
var vegetableWhereM = m_vegetable.Where(x => x.kind == 1);
// クエリ構文
var vegetableWhereQ = from x in m_vegetable
                      where x.kind == 1
                      select x;
```
絞り込むだけなら、メソッド構文で書いたほうがシンプル

### 選択(Select)
```c#:C#
// isRoot（x.kind == 1の場合：true、それ以外の場合：false）を追加
// メソッド構文
var vegetableSelectM = m_vegetable
                      .Select(x => new { x.id, x.name, x.kind, isRoot = x.kind == 1 });
// クエリ構文
var vegetableSelectQ = from x in m_vegetable
                       select new { x.id, x.name, x.kind, isRoot = x.kind == 1 };
```
selectが入ると、メソッド構文とクエリ構文の差が無くなる

### 連番付与(Select)
```c#:C#
// i（連番）を追加、x.kindを除外
// メソッド構文
var vegetableSelectAddIndexM = m_vegetable.Select((x, i) => new { i, x.id, x.name });
```
クエリ構文でも出来なくはないが、連番の付与はメソッド構文が良い


### 結合(Join)
```c#:C#
// 内部結合
// メソッド構文
var vegetableInnerJoinM = m_kind
                         .Join(m_vegetable, x => x.id, y => y.kind, (x, y) => new { y.id, y.name, kind_id = y.kind, kind_name = x.name });
// クエリ構文
var vegetableInnerJoinQ = from x in m_kind
                          join y in m_vegetable
                          on x.id equals y.kind
                          select new { y.id, y.name, kind_id = y.kind, kind_name = x.name };

// 外部結合
// メソッド構文
var vegetableOuterJoinM = m_kind
                         .GroupJoin(m_vegetable, x => x.id, y => y.kind, (x, y) => new { x, y })
                         .SelectMany(z => z.y.DefaultIfEmpty(new m_vegetable { id = 0, name = "", kind = 0 }), (z, w) => new { w.id, w.name, kind_id = z.x.id, kind_name = z.x.name });
// クエリ構文
var vegetableOuterJoinQ = from x in m_kind
                          join y in m_vegetable
                          on x.id equals y.kind into z
                          from w in z.DefaultIfEmpty(new m_vegetable { id = 0, name = "", kind = 0 })
                          select new { w.id, w.name, kind_id = x.id, kind_name = x.name };
```
結合についてはクエリ構文の方が分かりやすい