- 開発技術
C# LINQの機能について
- #LINQ
- C#

はじめに
【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc. 詳細はこちらから>
LINQ(Language Integrated Query)とは、C#コードの中で、SQLのようにコレクションデータに対して操作(検索・抽出・並び替えなど)を行う機能のことです。
コードの中でデータを絞ったり、並び替えたり、グループ化することができ、出力表示したいデータを簡単に操作したいときに便利です。SQL風の書き方 or メソッドチェーン(ラムダ式)で書く書き方があります。
LINQを使うためには、usingディレクティブを使ってSystem.Linqを参照する必要があります。
LINQの基本構文
■SQL風クエリ構文
list の中から 10より大きい 要素だけを取り出して、昇順に並べたもの
1 2 3 4 |
var result = from item in list where item > 10 orderby item select item; |
■メソッドチェーン構文(ラムダ式)
上記と同じ意味のメソッド形式(関数呼び出し)で書いたもの
1 2 3 4 |
var result = list.Where(x => x > 10) .OrderBy(x => x) .ToList(); ※ここで操作文が完成するので最後リスト化することを忘れずに! |
個人的にはラムダ式のほうが読み取りやすく、よく使われている印象があります。
よく使うLINQメソッドまとめ
メソッド名 |
役割 |
Where |
条件に合うものを抽出する |
Select |
データを変換・取り出す |
OrderBy / OrderByDescending |
昇順・降順に並べる |
GroupBy |
グループ化する |
Any |
1件でも条件を満たすか判定 |
All |
全部が条件を満たすか判定 |
FirstOrDefault |
最初の1件を取り出す(なければnull) |
Count |
件数を数える |
Sum, Max, Min, Average |
集計系メソッド |
Join |
内部結合 |
GroupJoin |
外部結合 |
基本的な使用例 ()
◆フィルター(Where)
1 |
var adults = people.Where (p => p.Age >= 20); |
◆取り出し(Select)
1 |
var names = people.Select(p => p.Name); |
◆ソート(OrderBy)
1 |
var sorted = people.OrderBy(p => p.Name); |
◆グループ化(GroupBy)
1 |
var groups = people.GroupBy(p => p.Department); |
◆条件判定(Any / All)
1 2 |
bool hasAdults = people.Any(p => p.Age >= 20); bool allAdults = people.All(p => p.Age >= 20); |
◆先頭取得(FirstOrDefault)
1 |
var firstAdult = people.FirstOrDefault(p => p.Age >= 20); |
◆ 内部結合(Join)
リストのキーとモデルのプロパティ名を指定して、結合後の形を設定する。
1 2 3 4 5 6 7 8 9 |
var result = listA.Join( listB, a => a.Id, // listA側のキー b => b.AId, // listB側のキー (a, b) => new { // 結合後の形 AName = a.Name, BTitle = b.Title } ); |
◆ 外部結合(GroupJoin)
C#のLINQ標準では、Joinメソッドに「外部結合」は直接ないので、GroupJoin → SelectMany → DefaultIfEmpty を使って書きます。
DefaultIfEmpty() は「マッチしなかったらnull」を返す。
Joinした後、値設定時にnullチェックして使う。※nullチェックを行う場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var result = listA .GroupJoin( listB, a => a.Id, b => b.AId, (a, bs) => new { a, bs } ) .SelectMany( temp => temp.bs.DefaultIfEmpty(), (temp, b) => new { AName = temp.a.Name, BTitle = b != null ? b.Title : "(なし)" } ); |
さらに複数テーブルを外部結合する場合↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var result = listA .GroupJoin( listB, a => a.Id, b => b.AId, (a, bs) => new { a, bs } ) .SelectMany( temp => temp.bs.DefaultIfEmpty(), (temp, b) => new { a = temp.a, b } ) .GroupJoin( listC, temp => temp.a.Id, c => c.AId, (temp, cs) => new { temp.a, temp.b, cs } ※ここで前の結合のテーブルを引き継ぐことを忘れずに! temp.a temp.bを引き継いできて、csは新規テーブルを表しているので最後に追加する。 より複数のテーブルの場合テーブルごとに引き継いでいく必要があるので段々増えていくイメージ。 ) .SelectMany( temp => temp.cs.DefaultIfEmpty(), (temp, c) => new { AName = temp.a.Name, BTitle = temp.b != null ? temp.b.Title : "(なし)", CContent = c != null ? c.Content : "(なし)" } ); |
まとめ
C# LINQとSQLは全くの別物ですが、LINQ機能では「SQLみたいにコレクション操作」でき、SQL風構文 と メソッド構文(ラムダ式) が選べます。
ソース内で直感的に フィルター、並び替え、変換、集計 などができるので処理の流れが読み取りやすいかと思います。
【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>