LINQ to Entitiesで複数キーのJoin

LINQ to Entitiesを使って、データベースのテーブルで複数のキーを使ったJoinを実現するには、匿名型で複数のキーを含むclassを作ればいい。

LINQ to EntitiesでJoinを組むと、慣れないとけっこう苦労したりする。単純なキーのJoinなら比較的に簡単だが、複数のキーをJoinするにはどうすればいいか悩んだことがあった。調べた結果、匿名型でキー項目を含むclassを作って、そのclass同士をequalsで結べばいいことがわかった。

以下に例を挙げてみる。

まずはTestという名前のデータベースを作成してTestA、TestBというテーブルを作成する。それぞれキー項目が二つになるようにTestIDとTestCodeを作成する。

TestID | TestCode | Data
-------|----------|--------
  1    |      101 | Data_1
  2    |      102 | Data_2
  3    |      103 | Data_3
  4    |      104 | Data_4
  5    |      105 | Data_5 ...(続くとする)

 

TestID | TestCode | Flag
-------|----------|------
  1    |      101 |    1
  2    |      102 |    2
  3    |      103 |    3
  4    |      104 |    4
  5    |      105 |    5 ...(続くとする)

これらのテーブルから以下のような結果を取得したい。

TestID | TestCode | Data   | Flag
-------|----------|--------|------
  1    |      101 | Data_1 |    1
  2    |      102 | Data_2 |    2
  3    |      103 | Data_3 |    3
  4    |      104 | Data_4 |    4
  5    |      105 | Data_5 |    5 ...(続くとする)

この結果をSQLで組んだ場合は比較的簡単だ。ただJoinで結べばいい。

select a.TestID, a.TestCode, a.Data, b.Flag from TestA a
inner join TestB b on a.TestID = b.TestID and a.TestCode = b.TestCode

これをLINQ to Entitiesで実現するには以下のようにする。

using System;
using System.Linq;

namespace LinqToEntitiesJoin
{
    class Program
    {
        static void Main(string[] args)
        {
            var entities = new TestEntities();
            var test = from a in entities.TestA
                       join b in entities.TestB on new { a.TestID, a.TestCode } equals new { b.TestID, b.TestCode }
                       select new { a.TestID, a.TestCode, a.Data, b.Flag };
            test.ToList().ForEach(item =>
                {
                    Console.WriteLine("TestID = {0}, TestCode = {1}, Data = {2}, Flag = {3}", item.TestID, item.TestCode, item.Data, item.Flag);
                });
        }
    }
}

ハイライトになっているところが味噌で、匿名型でキー項目を含むclassを作成して、それ同士をequalsで結んで同じ結果が返ってくるようにしている。

これで複数のキーでJoinされたデータの結果を取得することができる。

以下のようにclassを作成して明示的に指定してもかまわない。

using System;
using System.Linq;

namespace LinqToEntitiesJoin
{
    class Program
    {
        private class Key
        {
            public int TestID { get; set; }
            public int TestCode { get; set; }
        }

        static void Main(string[] args)
        {
            var entities = new TestEntities();
            var test = from a in entities.TestA
                       join b in entities.TestB on new Key() { TestID = a.TestID, TestCode = a.TestCode } equals new Key() { TestID = b.TestID, TestCode = b.TestCode }
                       select new { a.TestID, a.TestCode, a.Data, b.Flag };
            test.ToList().ForEach(item =>
                {
                    Console.WriteLine("TestID = {0}, TestCode = {1}, Data = {2}, Flag = {3}", item.TestID, item.TestCode, item.Data, item.Flag);
                });
        }
    }
}

Follow me!

Feedlyで新着記事をチェックしよう!

Feedlyでフォローしておけば、新着記事をチェックすることができます。ぜひ、この機会にFeedlyに追加しておきましょう。