LINQを使って3つのオブジェクトを結合する
今回は、データソースのオブジェクトを3つ用意して、LINQ を使って3つのオブジェクトを結合するやり方を解説します。
LINQ の結合に関する詳しい内容は、以下のマイクロソフト公式サイトを参照してください。
データソースの定義
今回用意するデータソースは、以下のようなイメージとなります。
項目 | 内容 |
---|---|
Id | 社員ID |
EmpName | 社員名 |
DepId | 部署ID |
LocId | 拠点ID |
項目 | 内容 |
---|---|
DepId | 部署ID |
DepName | 部署名 |
項目 | 内容 |
---|---|
LocId | 拠点ID |
LocName | 拠点名 |
データソース(社員)の部署IDと拠点IDを紐づけて、3つのオブジェクトを結合します。
データソースの作成
上記のデータソースの定義を元に、オブジェクトを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// データソース(社員) var data1 = new[] { new { Id=1, EmpName="山田太郎", DepId=1, LocId=1 }, new { Id=2, EmpName="佐藤花子", DepId=2, LocId=1 }, new { Id=3, EmpName="鈴木一朗", DepId=1, LocId=2 } }; // データソース(部署) var data2 = new[] { new { DepId=1, DepName="営業" }, new { DepId=2, DepName="経理" } }; // データソース(拠点) var data3 = new[] { new { LocId=1, LocName="本社" }, new { LocId=2, LocName="支社" } }; |
クエリ構文を使った結合
上記のオブジェクトをクエリ構文で結合する場合は、以下のように記述します。
from emp in data1
join dep in data2 on emp.DepId equals dep.DepId
join loc in data3 on emp.LocId equals loc.LocId
select new { emp.EmpName, dep.DepName, loc.LocName };
上記の例で使用している emp、dep、loc の名称は、何でも構いませんが、何を表しているかが分かりやすい名称にします。
select句では、結合後の新しいオブジェクトの項目(社員名、部署名、拠点名)を定義します。
メソッド構文を使った結合
メソッド構文で結合する場合は、以下のように記述します。
data1
.Join(
data2,
emp => emp.DepId,
dep => dep.DepId,
(emp, dep) => new { emp, dep })
.Join(
data3,
com => com.emp.LocId,
loc => loc.LocId,
(com, loc) => new { com.emp.EmpName, com.dep.DepName, loc.LocName}
);
Join()メソッドの引数の内容は、以下の通りです。
第2引数から第4引数は、ラムダ式で記載します。
第1引数:元のオブジェクトに結合するオブジェクト
第2引数:紐づける結合元の項目
第3引数:紐づける結合先の項目
第4引数:結合した新しいオブジェクトの項目(結合結果)
ここで注意が必要なのは、2番目のJoin()メソッドの第2引数は、1番目のJoin()メソッドで作成した新しいオブジェクトを受け取って、com として定義していることです。(名称は何でも構いません)
com の中に、データソース(社員)とデータソース(部署)の内容が格納されているので、その中の拠点IDを使って拠点オブジェクトと結合します。
LINQでオブジェクトを結合したプログラムを作成する
これまでの内容を元に、実際に動作するプログラムを作成してみましょう。
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
namespace LinqSample3 { internal class Program { static void Main(string[] args) { // データソース(社員) var data1 = new[] { new { Id=1, EmpName="山田太郎", DepId=1, LocId=1 }, new { Id=2, EmpName="佐藤花子", DepId=2, LocId=1 }, new { Id=3, EmpName="鈴木一朗", DepId=1, LocId=2 } }; // データソース(部署) var data2 = new[] { new { DepId=1, DepName="営業" }, new { DepId=2, DepName="経理" } }; // データソース(拠点) var data3 = new[] { new { LocId=1, LocName="本社" }, new { LocId=2, LocName="支社" } }; // クエリ構文 var query1 = from emp in data1 join dep in data2 on emp.DepId equals dep.DepId join loc in data3 on emp.LocId equals loc.LocId select new { emp.EmpName, dep.DepName, loc.LocName }; foreach (var x in query1) { Console.WriteLine($"{x.EmpName} {x.DepName} {x.LocName}"); } // メソッド構文 var query2 = data1 .Join( data2, emp => emp.DepId, dep => dep.DepId, (emp, dep) => new { emp, dep }) .Join( data3, com => com.emp.LocId, loc => loc.LocId, (com, loc) => new { com.emp.EmpName, com.dep.DepName, loc.LocName} ); foreach (var x in query2) { Console.WriteLine($"{x.EmpName} {x.DepName} {x.LocName}"); } } } } |
実行結果
山田太郎 営業 本社
佐藤花子 経理 本社
鈴木一朗 営業 支社
山田太郎 営業 本社
佐藤花子 経理 本社
鈴木一朗 営業 支社