LINQで外部結合を実装する

SQL で外部結合をする場合は、さくっと left join や *= などを使えば良いのですが、LINQ だといまいち不明。

だったので、探してみました。

Visual Studio 2010 – Visual C#
方法 : 左外部結合を実行する (C# プログラミング ガイド)
http://msdn.microsoft.com/ja-jp/library/bb397895.aspx

という感じで、モロ、そのままの記事がありました。以前は、LINQ関係は調べるのが大変だったのですが、これは良さそうですね。

備忘録も込みで、解説を加えておくと、

  • Person、Pet というテーブルがあります。
  • Person(人)は、Pet(ペット)を飼っている、というイメージですね。
  • Personには、ペットを飼っていない人もいます。

        public class Person
        {
            public string FirstName { get; set; }
            public int? PetID { get; set; }
        }
        public class Pet
        {
            public int ID { get; set; }
            public string PetName { get; set; }
        }
        List<Person> persons;
        List<Pet> pets;

こんな風にデータを初期化しておきます。

        // 初期化
        private void button1_Click(object sender, EventArgs e)
        {
            persons = new List<Person>();
            persons.Add(new Person() { FirstName = “masuda”, PetID = 1 });
            persons.Add(new Person() { FirstName = “tomoaki”, PetID = null });
            persons.Add(new Person() { FirstName = “kyonpu”, PetID = 2 });

            pets = new List<Pet>();
            pets.Add( new Pet() { ID=1, PetName=”taro” });
            pets.Add( new Pet() { ID=2, PetName=”risumo” });
        }

■ペットを飼っている人(内部結合)

        // 内部結合
        private void button2_Click(object sender, EventArgs e)
        {
            // ペットがいる人を表示
            var ret = from pe in persons
                      join pet in pets on pe.PetID equals pet.ID
                      select new { pe.FirstName, pet.PetName };

            foreach (var it in ret)
            {
                Debug.Print(it.ToString());
            }
        }

■ペットを飼っている人もそうでない人も表示(外部結合)

        // 外部結合
        private void button3_Click(object sender, EventArgs e)
        {
            // ペットがいる/いないに関わらず表示
            var ret = from pe in persons
                      join pet in pets on pe.PetID equals pet.ID into sub
                      from t in sub.DefaultIfEmpty()
                      select new {  pe.FirstName, PetName = ( t == null ? “”: t.PetName )};

            foreach (var it in ret)
            {
                Debug.Print(it.ToString());
            }
        }

■ペットを飼っていない人だけを表示(null比較)

        // 外部結合(nullのみ抽出)
        private void button4_Click(object sender, EventArgs e)
        {
            // ペットがいない人を表示
            var ret = from pe in persons
                      join pet in pets on pe.PetID equals pet.ID into sub
                      from t in sub.DefaultIfEmpty()
                      where t == null
                      select new { pe.FirstName };

            foreach (var it in ret)
            {
                Debug.Print(it.ToString());
            }
        }

こんな風に、一度 into を使ってサブテーブル(sub)を用意してから、DefaultIfEmpty メソッドで外部結合を実現する、という方法になります。

 

カテゴリー: 開発 パーマリンク