Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

IEnumerable.GroupJoinメソッド

Enumerable.GroupJoin(TOuter, TInner, TKey, TResult) メソッド (IEnumerable(TOuter), IEnumerable(TInner), Func(TOuter, TKey), Func(TInner, TKey), Func(TOuter, IEnumerable(TInner), TResult)) (System.Linq)
キーが等しいかどうかに基づいて 2 つのシーケンスの要素を相互に関連付け、その結果をグループ化します。 キーの比較には既定の等値比較子が使用されます。

SQLでは、LEFT OUTER JOINまたはRIGHT OUTER JOINに相当します。

ソースコード

using System;
using System.Linq;

namespace LinqSample {
    class Program {
        static void Main(string[] args) {
            Man[] mans = new Man[] { 
                new Man() { Name = "suzuki taro", PetName = "horse" },
                new Man() { Name = "suzuki jiro", PetName = null },
                new Man() { Name = "sato taro", PetName = "cat" },
                new Man() { Name = "sato jiro", PetName = "dog" }
            };

            Pet[] pets = new Pet[] {
                new Pet() { Name = "dog", Food = "meat" },
                new Pet() { Name = "cat", Food = "fish" },
                new Pet() { Name = "horse", Food = "grass" }
            };

            var q = mans.GroupJoin(
                pets, 
                man => man.PetName, // JOINのキー
                pet => pet.Name,    // JOINのキー
                (man, pet) => new { ManName = man.Name, Pets = pet.DefaultIfEmpty() })
            // シーケンスの展開
            .SelectMany(o => o.Pets, (o, p) => new {
                ManName = o.ManName,
                PetName = p == null ? "Null" : p.Name,
                Food = p == null ? "Null" : p.Food
            });

            foreach (var o in q) {
                Console.WriteLine("Man = {0}, Pet = {1}, Food = {2}", o.ManName, o.PetName, o.Food);
            }
            Console.ReadKey();
        }
    }

    class Man {
        public string Name { get; set; }
        public string PetName { get; set; }
    }

    class Pet {
        public string Name { get; set; }
        public string Food { get; set; }
    }
}

実行結果