星期六, 4月 13, 2019

[EF] TPH

該篇為 MSDN 文章 - 設計工具的 TPH 繼承 的練習筆記

Table Per Hierarchy (TPH) MSDN 解釋:使用一個資料庫資料表來維護繼承階層架構中的實體類型的所有資料,了解過後,個人解讀是,Table 沒有正規化情況下,在 Entity 進行正規化並進行 Coding

Person Table 說明,Discriminator 為 Studnet 或 Instructor 兩種類別
  • Discriminator = Studnet 時,使用 EnrollmentDate,HireDate 不使用為 null
  • Discriminator = Instructor 時,使用 HireDate,EnrollmentDate 不使用為 null
[EF] TPH-14


先建立 ADO.NET 實體模型並把 Person Table 拉進去後,手動建立 Student 和 Instrument Entity,步驟如下

[EF] TPH-1

加入 Studnet 和 Instrument Entity 時,[基底類型] 必須選擇 Person

[EF] TPH-2

在 Perosn Entity 上
  • 剪下 EnrollmentDate Property 並貼到 Studnet Entity 上
  • 剪下 HireDate Property 並貼到 Instrutor Entity 上
步驟如下
[EF] TPH-3

[EF] TPH-4

剪下貼上完成圖

[EF] TPH-5

把 Student.EnrollmentDate 和 Instructor.HireDate Property 設為不允許 null

[EF] TPH-7

把 Person Entity 設為 Abstract 同時也限制不能新增 Person Entity

[EF] TPH-8

刪除 Person.Discriminator Property

[EF] TPH-6

針對 Instructor 和 Student Entity 進行條件對應 (Condition Mapping)

[EF] TPH-9

設定完成圖

[EF] TPH-10

C# 測試 Code
namespace EFTPH
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new SchoolEntities())
            {
                // 新增 Student 或 Instructor 時,不需要輸入 Discriminator 資訊
                context.Person.Add(new Student() { LastName = "張", FirstName = "三", EnrollmentDate = new DateTime(2019, 4, 12) });
                context.Person.Add(new Instructor() { LastName = "李", FirstName = "四", HireDate = new DateTime(2015, 5, 5) });
                context.SaveChanges();

                // 抓出新增兩筆資料-張三、李四
                var InsertResult = context.Person.Where(w => w.LastName == "張" || w.LastName == "李");
                Console.WriteLine("============ 顯示新增資料 ============");
                foreach (var p in InsertResult)
                {
                    Console.WriteLine($"FullName:{p.LastName}{p.FirstName}");
                }

                // 顯示新增 Instructor 資料
                Console.WriteLine("============ 顯示 Instructor 資料 ============");
                foreach (var i in InsertResult.OfType<Instructor>())
                {
                    Console.WriteLine($"FullName:{i.LastName}{i.FirstName}-HireDate:{i.HireDate.ToShortDateString()}");
                }

                // 顯示新增 Student 資料
                Console.WriteLine("============ 顯示 Student 資料 ============");
                foreach (var s in InsertResult.OfType<Student>())
                {
                    Console.WriteLine($"FullName:{s.LastName}{s.FirstName}-EnrollmentDate:{s.EnrollmentDate.ToShortDateString()}");
                }
            }
        }
    }
}
執行結果

[EF] TPH-13

Person Table 資料觀察

[EF] TPH-11

條件對應輸入完後,假如沒有把 Perosn.Discriminator 刪除,驗證後會出現下圖錯誤

[EF] TPH-12

MSDN 解釋
我們想要移除的原因鑑別子屬性,是因為您不能超過一次對應資料表資料行。本專欄將用於條件式對應,因此無法用於屬性以及對應。它可以用於兩者,如果條件使用的唯一方式Is Null或是Is Not Null比較。

沒有留言:

張貼留言