設計工具 TPT 繼承

這個逐步解說示範如何使用 Entity Framework Designer (EF Designer) 在模型中實作每一類型資料表 (TPT) 繼承。 一類一表 (Table-Per-Type) 繼承會在資料庫中使用個別資料表來維護繼承階層架構 (Inheritance Hierarchy) 中每一個類型的非繼承屬性和索引鍵屬性。

在本逐步解說中,我們會將 Course (基底類型)、 OnlineCourse (衍生自 Course )和 OnsiteCourse (衍生自 Course ) 實體對應至具有相同名稱的資料表。 我們將從資料庫建立模型,然後改變模型以實作 TPT 繼承。

您也可以從 Model First 開始,然後從模型產生資料庫。 EF 設計工具預設會使用 TPT 策略,因此模型中的任何繼承都會對應至不同的資料表。

其他繼承選項

資料表個別階層 (TPH) 是另一種繼承類型,其中一個資料庫資料表用來維護繼承階層中所有實體類型的資料。  如需如何使用實體設計工具對應資料表個別階層繼承的資訊,請參閱 EF Designer TPH 繼承 。 

請注意,Entity Framework 執行時間支援資料表個別具象類型繼承(TPC)和混合繼承模型,但 EF 設計工具不支援。 如果您想要使用 TPC 或混合繼承,您有兩個選項:使用 Code First,或手動編輯 EDMX 檔案。 如果您選擇使用 EDMX 檔案,[對應詳細資料] 視窗將會進入「安全模式」,而且您將無法使用設計工具來變更對應。

必要條件

若要完成這個逐步解說,您將需要:

設定專案

  • 開啟 Visual Studio 2012。
  • 選取 [檔案- > 新增 - 專案] >
  • 在左窗格中,按一下 [Visual C# ],然後選取 主控台 範本。
  • 輸入 TPTDBFirstSample 作為名稱。
  • 選取 [確定]。

建立模型

  • 以滑鼠右鍵按一下方案總管中的專案,然後選取 [ 新增 - > 新增專案 ]。
  • 從左側功能表中選取 [資料 ],然後在 [範本] 窗格中選取 [ADO.NET 實體資料模型 ]。
  • 針對檔案名輸入 TPTModel.edmx ,然後按一下 [ 新增 ]。
  • 在 [選擇模型內容] 對話方塊中,選取 [從資料庫產生],然後按 [ 下一步 ]。
  • 按一下 [ 新增連線。 在 [連線ion 屬性] 對話方塊中,輸入伺服器名稱 (例如 , localdb)\mssqllocaldb ),選取驗證方法,輸入 School 以取得資料庫名稱,然後按一下 [ 確定 ]。 [選擇您的資料連線] 對話方塊會使用您的資料庫連線設定來更新。
  • 在 [選擇資料庫物件] 對話方塊的 [資料表] 節點底下,選取 [部門 ]、 [課程]、[OnlineCourse] 和 [OnsiteCourse ] 資料表。
  • 按一下完成

[實體設計工具] 會顯示為編輯模型提供設計介面。 您在 [選擇資料庫物件] 對話方塊中選取的所有物件都會新增至模型。

實作每一類型的資料表繼承

  • 在設計介面上,以滑鼠右鍵按一下 OnlineCourse 實體類型,然後選取 [ 屬性 ]。
  • 在 [ 屬性] 視窗中,將 [基底類型] 屬性設定為 Course
  • 滑鼠右鍵按一下 OnsiteCourse 實體類型,然後選取 [ 屬性 ]。
  • 在 [ 屬性] 視窗中,將 [基底類型] 屬性設定為 Course
  • 以滑鼠右鍵按一下 OnlineCourse Course 實體類型之間的 關聯(行)。 選取 [ 從模型 刪除]。
  • 以滑鼠右鍵按一下 OnsiteCourse Course 實體類型之間的 關聯。 選取 [ 從模型 刪除]。

我們現在將從 OnlineCourse OnsiteCourse 刪除 CourseID 屬性 ,因為這些類別會繼承 CourseID Course 基底類型。

  • 以滑鼠右鍵按一下 OnlineCourse 實體類型的 CourseID 屬性 ,然後選取 [從模型 刪除]。
  • 以滑鼠右鍵按一下 OnsiteCourse 實體類型的 CourseID 屬性 ,然後選取 [從模型刪除]
  • 現已實作一類一表 (Table-Per-Type) 繼承。

Table Per Type

使用模型

開啟定義 Main 方法的 Program.cs 檔案。 將下列程式碼貼到 Main 函式中。 程式碼會執行三個查詢。 第一個查詢會帶回與指定部門相關的所有 課程 。 第二個查詢會使用 OfType 方法傳回 與指定部門相關的 OnlineCourses 。 第三個查詢會傳 回 OnsiteCourses

    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);
            }
        }
    }