デザイナーの TPT 継承

このステップバイステップのチュートリアルでは、Entity Framework Designer (EF Designer) を使用して、モデルに Table-Per-Type (TPT) 継承を実装する方法について説明します。 Table-Per-Type 継承は、データベース内の別個のテーブルを使用して、非継承プロパティと継承階層のそれぞれの型のキー プロパティのデータを維持します。

このチュートリアルでは、Course (基本データ型)、OnlineCourse (Course から派生)、OnsiteCourse (Course から派生) の各エンティティを同じ名前のテーブルにマップします。 データベースからモデルを作成し、モデルを変更して TPT 継承を実装します。

Model First から始めて、モデルからデータベースを生成することもできます。 EF Designer では、既定で TPT 戦略を使用するため、モデル内の継承は個別のテーブルにマップされます。

他の継承オプション

Table-Per-Hierarchy (TPH) は、1 つのデータベース テーブルを使用して、継承階層のすべてのエンティティ型のデータを保持する別の種類の継承です。  Entity Designer を使用して Table-Per-Hierarchy 継承をマップする方法については、EF Designer の TPH 継承に関する記事を参照してください。 

Table-Per-Concrete type (TPC) 継承モデルと混合継承モデルは、Entity Framework ランタイムではサポートされていますが、EF Designer ではサポートされていません。 TPC または混合継承を使用する場合、Code First の使用または EDMX ファイルの手動編集の 2 つの方法があります。 EDMX ファイルを使用する場合、[マッピングの詳細] ウィンドウは "セーフ モード" になり、デザイナーを使用してマッピングを変更することはできなくなります。

前提条件

このチュートリアルを完了するための要件を次に示します。

プロジェクトをセットアップする

  • Visual Studio 2012 を開きます。
  • [ファイル] -> [新規作成] -> [プロジェクト] の順に選択します。
  • 左ペインで [Visual C#] をクリックし、[コンソール] テンプレートを選択します。
  • 名前として「TPTDBFirstSample」と入力します。
  • [OK] を選択します。

Create a Model (モデルの作成)

  • ソリューション エクスプローラーでプロジェクトを右クリックし、[追加] -> [新しい項目] の順に選択します。
  • 左側のメニューから [データ] を選択し、[テンプレート] ペインの [ADO.NET Entity Data Model] を選択します。
  • ファイル名として「TPTModel.edmx」と入力し、[追加] をクリックします。
  • [モデルのコンテンツの選択] ダイアログ ボックスで、**[データベースから生成]** を選択し、[次へ] をクリックします。
  • [新しい接続] をクリックします。 [接続のプロパティ] ダイアログ ボックスで、サーバー名 (例: (localdb)\mssqllocaldb) を入力し、認証方法を選択します。データベース名として「School」と入力し、[OK] をクリックします。 指定したデータベース接続設定に従って、[データ接続の選択] ダイアログ ボックスが更新されます。
  • [データベース オブジェクトの選択] ダイアログ ボックスで、[テーブル] ノードの DepartmentCourse、OnlineCourse、OnsiteCourse の各テーブルを選択します。
  • [完了] をクリックします。

モデルを編集するためのデザイン サーフェイスを提供する Entity Designer が表示されます。 [データベース オブジェクトの選択] ダイアログ ボックスで選択したすべてのオブジェクトがモデルに追加されます。

Table-Per-Type 継承を実装する

  • デザイン サーフェイスで OnlineCourse エンティティ型を右クリックし、[プロパティ] を選択します。
  • [プロパティ] ウィンドウで、[基本データ型] プロパティを Course に設定します。
  • OnsiteCourse エンティティ型を右クリックし、[プロパティ] をクリックします。
  • [プロパティ] ウィンドウで、[基本データ型] プロパティを Course に設定します。
  • OnlineCourse エンティティ型と Course エンティティ型の間の関連付け (線) を右クリックします。 [モデルから削除] を選択します。
  • OnsiteCourse エンティティ型と Course エンティティ型の間の関連付けを右クリックします。 [モデルから削除] を選択します。

OnlineCourseOnsiteCourse は、Course 基本データ型から CourseID を継承するため、これらのクラスから CourseID プロパティを削除します。

  • OnlineCourse エンティティ型の CourseID プロパティを右クリックし、[モデルから削除] を選択します。
  • OnsiteCourse エンティティ型の CourseID プロパティを右クリックし、[モデルから削除] を選択します。
  • これで、Table-Per-Type 継承が実装されました。

Table Per Type

モデルを使用する

Main メソッドが定義されている Program.cs ファイルを開きます。 Main 関数に次のコードを貼り付けます。 このコードでは、3 つのクエリが実行されます。 最初のクエリでは、指定された部門に関連するすべての Course が返されます。 2 番目のクエリでは、OfType メソッドを使用して、指定された部門に関連する OnlineCourse が返されます。 3 番目のクエリでは、OnsiteCourse が返されます。

    using (var context = new SchoolEntities())
    {
        foreach (var department in context.Departments)
        {
            Console.WriteLine("The {0} department has the following courses:",
                               department.Name);

            Console.WriteLine("   All courses");
            foreach (var course in department.Courses )
            {
                Console.WriteLine("     {0}", course.Title);
            }

            foreach (var course in department.Courses.
                OfType<OnlineCourse>())
            {
                Console.WriteLine("   Online - {0}", course.Title);
            }

            foreach (var course in department.Courses.
                OfType<OnsiteCourse>())
            {
                Console.WriteLine("   Onsite - {0}", course.Title);
            }
        }
    }