LINQのGroupJoinを使ってみる

LINQに普通のJoinのほかにGroupJoinという機能がありますので、ちょっと使って遊んでみました。

通常のJoinの場合

                    var 商品リスト = new[] { new { 商品番号 = "A", 商品名 = "鼻毛カッター" }, 
                                         new { 商品番号 = "B", 商品名 = "安全ハサミ" },
                                         new { 商品番号 = "C", 商品名 = "ラジオペンチ"}};

                    var 在庫リスト = new[] { new { 商品番号 = "A", 数量 = 30 ,LotNo = 1} ,
                                            new { 商品番号 = "A", 数量 = 40 ,LotNo = 2} ,
                                            new { 商品番号 = "A", 数量 = 50 ,LotNo = 3} ,
                                            new { 商品番号 = "A", 数量 = 60 ,LotNo = 4} ,
                                            new { 商品番号 = "A", 数量 = 70 ,LotNo = 5} ,
                                            new { 商品番号 = "A", 数量 = 90 ,LotNo = 6} ,
                                            new { 商品番号 = "A", 数量 = 80 ,LotNo = 7} ,
                                            new {商品番号 = "C",数量 = 69,LotNo = 8}};

                       var 商品別LOTNO別リスト = from 商品 in 商品リスト
                                       join 在庫 in 在庫リスト
                                       on 商品.商品番号 equals 在庫.商品番号
                                       select new
                                       {
                                           商品番号 = 商品.商品番号,
                                           商品名 = 商品.商品名,
                                           LOTNO = 在庫.LOTNO,
                                           数量 = 在庫.数量
                                       };

というように二つの匿名型の配列を商品番号で結合したときの結果は

                    var 商品別LOTNO別リスト = new[] { new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 30 ,LotNo = 1} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 40 ,LotNo = 2} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 50 ,LotNo = 3} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 60 ,LotNo = 4} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 70 ,LotNo = 5} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 90 ,LotNo = 6} ,
                                            new { 商品番号 = "A", 商品名 = "鼻毛カッター", 数量 = 80 ,LotNo = 7} ,
                                            new {商品番号 = "C",, 商品名 = "ラジオペンチ", 数量 = 69,LotNo = 8}};

というように、SQLでINNER JOINをする時と同じような結果になります。
つまり、商品リストの商品番号に対して在庫リスト中に同じ商品番号があれば、それだけオブジェクトが作られます。
もちろん、対象の商品番号が無かったオブジェクトは作られません。


大して、

                    var 商品リスト = new[] { new { 商品番号 = "A", 商品名 = "鼻毛カッター" }, 
                                         new { 商品番号 = "B", 商品名 = "安全ハサミ" },
                                         new { 商品番号 = "C", 商品名 = "ラジオペンチ"}};

                    var 在庫リスト = new[] { new { 商品番号 = "A", 数量 = 30 ,LotNo = 1} ,
                                            new { 商品番号 = "A", 数量 = 40 ,LotNo = 2} ,
                                            new { 商品番号 = "A", 数量 = 50 ,LotNo = 3} ,
                                            new { 商品番号 = "A", 数量 = 60 ,LotNo = 4} ,
                                            new { 商品番号 = "A", 数量 = 70 ,LotNo = 5} ,
                                            new { 商品番号 = "A", 数量 = 90 ,LotNo = 6} ,
                                            new { 商品番号 = "A", 数量 = 80 ,LotNo = 7} ,
                                            new {商品番号 = "C",数量 = 69,LotNo = 8}};

                    var 商品別在庫リスト = from 商品 in 商品リスト
                                 join 在庫 in 在庫リスト

                                 on 商品.商品番号 equals 在庫.商品番号 into 商品別在庫
                                   select new
                                   {   商品番号 = 商品.商品番号,
                                       商品名 = 商品.商品名,
                                       数量 = 商品別在庫.Sum(x => x.数量)
                                 };

                    foreach (var 商品別在庫 in 商品別在庫リスト)
                    {
                        Console.WriteLine(string.Format("商品番号:{0} 商品名:{1} 在庫数量:{2}", 
							商品別在庫.商品番号, 
							商品別在庫.商品名, 
							商品別在庫.数量));
                    }


Join ... Intoという構文で上記のようにGroupJoinをすると、

                    var 商品別在庫リスト = new[] { new { 商品番号 = "A", 商品名 = "鼻毛カッター" ,数量 = 420}, 
                                         new { 商品番号 = "B", 商品名 = "安全ハサミ" ,数量 = 0},
                                         new { 商品番号 = "C", 商品名 = "ラジオペンチ",数量 = 69}};

というように、商品リストの商品番号と同じ商品番号の在庫は集約されて結合されますので、商品番号単位に在庫リストが作成されることになり、商品番号別の数量の合計を出力する事が可能です。
また、在庫リストに対象の商品番号が無いオブジェクトも作られます。