8表翻譯模板 2-8 Table per Type Inheritance 建模
日期:2023-03-11 12:39:36 / 人氣: 780 / 發(fā)布者:成都翻譯公司
2、使用代碼清單2-16創(chuàng)建一個POCO實體Business;代碼清單2-19的輸出如下:按下面的步驟,為表Account建模,模型中實體類型只代表激活狀態(tài)的賬戶代碼清單2-20演示了從Account表插入和獲取數(shù)據(jù)。之所有這樣做,是因為我們需要插入一行DeletedOn列為非null值的數(shù)據(jù)。翻譯的初衷以及為什么選擇《Entity Framework 6 Recipes》來學習,請看本系列開頭
2-8 每個類型繼承建模的表
問題
您有這樣一個數(shù)據(jù)庫表,其中包含一些附加信息,這些信息屬于公共表。您想使用 Table per Type Inheritance (TPT) 繼承映射建模。
解決方案
假設(shè)您有兩個與公共表密切相關(guān)的表。如圖 2-17 所示,Businiss 表與 eCommerce 表和 Retail 表具有 1:0...1 關(guān)系。*重要的是,eCommerce 表和Retail 表具有有關(guān)Business 表中表示的業(yè)務(wù)的附加信息。(企業(yè) ID)。
圖 2-17 密切相關(guān)的表
餐桌零售和電子商務(wù)與餐桌業(yè)務(wù)密切相關(guān),它們包含一些與業(yè)務(wù)密切相關(guān)的屬性。按照以下步驟使用 TPT 對這種繼承進行建模(零售和電子商務(wù)實體從業(yè)務(wù)實體繼承)。
1、 在你的項目中創(chuàng)建一個繼承自 DbContext 的上下文對象 EF6RecipesContext;
2、 使用代碼清單2-16創(chuàng)建POCO實體Business;
代碼清單2-16 創(chuàng)建POCO實體業(yè)務(wù)
1 [Table("Business", Schema = "Chapter2")] 2 public class Business { 3 [Key] 4 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 5 public int BusinessId { get; protected set; } 6 public string Name { get; set; } 7 public string LicenseNumber { get; set; } 8 }
3、 使用代碼清單2-17創(chuàng)建一個POCO實體eCommerce,它繼承自Business類
代碼清單 2-17 創(chuàng)建 POCO 實體 eCommerce
1 [Table("eCommerce", Schema = "Chapter2")] 2 public class eCommerce : Business { 3 public string URL { get; set; } 4 }
4、 使用代碼清單2-18創(chuàng)建一個POCO實體Retail,它繼承到Business類
代碼清單 2-18 創(chuàng)建 POCO 實體零售
1 [Table("Retail", Schema = "Chapter2")] 2 public class Retail : Business { 3 public string Address { get; set; } 4 public string City { get; set; } 5 public string State { get; set; } 6 public string ZIPCode { get; set; } 7 }
5.給上下文對象EF6RecipesContext添加DbSet屬性;函數(shù)如下代碼清單2-18-1)
1 public Recipe8Context() 2 : base("name=EF6CodeFirstRecipesContext") 3 { 4 5 }
原則
表Retail 和eCommerce 位于0...1 的一側(cè),與表Business 的關(guān)系為1:0...1。這意味著企業(yè)不能有額外的信息,或額外的零售和電子商務(wù)信息。在面向?qū)ο缶幊讨?,我們有一個基類 Business 和兩個派生類,Retail 和 eCommerce。
由于1:0...1的關(guān)系,在Retail和eCommerce表中,不可能有表Business中沒有對應(yīng)行的數(shù)據(jù)(行)。在面向?qū)ο笾校缮惱^承基類的屬性,是繼承的核心。在每個類型的表(通常稱為 TPT)映射中,每個派生類都表示為一個單獨的表。
代碼清單 2-19 演示了從模型中插入和獲取
代碼清單2-19 在TPT模型中插入和獲取實體
1 using (var context = new EF6RecipesContext()) { 2 var business = new Business { 3 Name = "Corner Dry Cleaning", 4 LicenseNumber = "100x1" 5 }; 6 context.Businesses.Add(business); 7 var retail = new Retail { 8 Name = "Shop and Save", 9 LicenseNumber = "200C", 10 Address = "101 Main", 11 City = "Anytown", 12 State = "TX", 13 ZIPCode = "76106" 14 }; 15 context.Businesses.Add(retail); 16 var web = new eCommerce { 17 Name = "BuyNow.com", 18 LicenseNumber = "300AB", 19 URL = "www.buynow.com" 20 }; 21 context.Businesses.Add(web); 22 context.SaveChanges(); 23 } 24 using (var context = new EF6RecipesContext()) { 25 Console.WriteLine(" --- All Businesses ---"); 26 foreach (var b in context.Businesses) { 27 Console.WriteLine("{0} (#{1})", b.Name, b.LicenseNumber); 28 } 29 Console.WriteLine(" --- Retail Businesses ---"); 30 foreach (var r in context.Businesses.OfType()) { 31 Console.WriteLine("{0} (#{1})", r.Name, r.LicenseNumber); 32 Console.WriteLine("{0}", r.Address); 33 Console.WriteLine("{0}, {1} {2}", r.City, r.State, r.ZIPCode); 34 } 35 Console.WriteLine(" --- eCommerce Businesses ---"); 36 foreach (var e in context.Businesses.OfType ()) { 37 Console.WriteLine("{0} (#{1})", e.Name, e.LicenseNumber); 38 Console.WriteLine("Online address is: {0}", e.URL); 39 } 40 }
代碼清單 2-19 創(chuàng)建并初始化了 Business 實體的一個實例和兩個派生類的實例。使用上下文中設(shè)置的業(yè)務(wù)實體中的 Add() 方法將它們添加到上下文中。
在查詢中,我們迭代上下文中設(shè)置的 Businesses 實體以訪問所有業(yè)務(wù)。對于派生類型,我們使用泛型方法 OfType() 并通過指定特定類型參數(shù)在實體集中進行過濾。
代碼清單2-19的輸出如下:
--- 所有企業(yè) --- 角落干洗 (#100X1)
購物省錢 (#200C)
(#300AB)
--- 零售業(yè)務(wù) --- 購物省錢 (#200C)
101 主
Anytown,德克薩斯州 76106
---- 電子商務(wù)企業(yè) (#300AB)
網(wǎng)上地址是:
TPT 是實體框架支持的三種繼承映射之一。另外兩個是 Table per Hierarchy(TPH,將在本章后面討論)和 Table per Concrete Type(TPC,見第 15 章)。
TPT 繼承映射為數(shù)據(jù)庫提供了靈活性。作為開發(fā)人員,我們可以輕松地為模型中新添加的表添加派生類型。但是,每個派生類型都會涉及一個額外的連接連接,這會降低系統(tǒng)的性能。在實際應(yīng)用中,我們已經(jīng)看到了派生類型較多時使用TPT繼承映射導致的性能問題。
每層級表 (TPH) 繼承映射將在第 2-10 節(jié)中描述。它將整個繼承類型存儲在單獨的表中。解決了TPT中的join連接問題,帶來了不錯的性能。但以犧牲數(shù)據(jù)庫的靈活性為代價。
每個具體的表 (TPC) 繼承映射,它在運行時由實體框架支持,但由設(shè)計器不支持。TPC 的重要應(yīng)用見第 15 章。
2-9 使用條件過濾對象集
問題
您想在實體類型上創(chuàng)建固定條件以映射表中行的子集。
解決方案
假設(shè)您有一個包含帳戶信息的數(shù)據(jù)庫表,如圖 2-18 所示。該表有一個可以為空的列 DeletedOn,用于存儲帳戶被刪除的日期和時間。如果賬戶被激活,列DeletedOn的值為空,并且你希望實體類型只代表激活的賬戶,即沒有DeletedOn值的賬戶。
圖 2-18 帶有 DeletedOn 列表的 Account 表
按照以下步驟為表 Account 建模。模型中的實體類型僅代表活躍賬戶
1、 右鍵單擊??您的項目,選擇 Add ?New Item8表翻譯模板,然后在 Visual C# 條目下的 Data 模板下選擇 ADO.NET Entity Data Model。
2、選擇從數(shù)據(jù)庫生成以從現(xiàn)有數(shù)據(jù)庫創(chuàng)建模型,然后單擊下一步。
3、您可以選擇一個現(xiàn)有的數(shù)據(jù)庫連接,也可以選擇創(chuàng)建一個新的數(shù)據(jù)庫連接。
4、 在選擇數(shù)據(jù)庫窗口中,選擇表帳戶。然后選中復選框以確定生成的對象名稱的單數(shù)和復數(shù)形式,并在模型中包含外鍵列。單擊完成
5、 如果未顯示映射詳細信息窗口,則單擊帳戶實體并查看映射詳細信息窗口。選擇工具菜單查看(查看)? 其他窗口(其他窗口)? 實體數(shù)據(jù)模型映射詳細信息(實體數(shù)據(jù)模型映射詳細信息)。單擊映射詳細信息窗口中的添加條件8表翻譯模板,然后選擇列 DeletedOn,在運算符列中,選擇是,在值/屬性列中,選擇空。這是它創(chuàng)建了一個映射條件(圖2-18)
6、 右擊DeletedOn 屬性,選擇Delete,因為我們使用列DeletedOn 作為條件映射,所以不映射到實體中的屬性。在我們的模型中,它的值始終為 Null。
原則
在示例中,我們在實體 Account 中應(yīng)用 Is Null 條件來過濾 DeletedOn 列中有值的行。清單 2-20 演示了從 Account 表中插入和檢索數(shù)據(jù)。
代理清單 2-20 從 Account 插入和獲取數(shù)據(jù)
1 using (var context = new EF6RecipesContext()) { 2 context.Database.ExecuteSqlCommand(@"insert into chapter2.account 3 (DeletedOn,AccountHolderId) values ('2/10/2009',1728)"); 4 var account = new Account { AccountHolderId = 2320 }; 5 context.Accounts.Add(account); 6 account = new Account { AccountHolderId = 2502 }; 7 context.Accounts.Add(account); 8 account = new Account { AccountHolderId = 2603 }; 9 context.Accounts.Add(account); 10 context.SaveChanges(); 11 } 12 using (var context = new EF6RecipesContext()) { 13 foreach (var account in context.Accounts) { 14 Console.WriteLine("Account Id = {0}", 15 account.AccountHolderId.ToString()); 16 } 17 }
代碼清單2-20,我們使用傳統(tǒng)方法調(diào)用上下文對象的Database屬性中的ExecuteSqlCommand()方法向數(shù)據(jù)庫中插入一行數(shù)據(jù)。這一切都是因為我們需要在 DeletedOn 列中插入一行非空值的數(shù)據(jù)。在模型中,Account 實體沒有映射此列的屬性。實際上,Account 實體不可能映射到DeletedOn 列的值的行,而這恰好是我們需要測試的。
對于第一部分代碼的其余部分,我們創(chuàng)建并初始化了 Account 實體類型的 3 個實例,并通過 SaveChanges() 方法將它們保存到數(shù)據(jù)中。
當我們查詢數(shù)據(jù)數(shù)據(jù)庫時,通過SaveChanges()方法只能得到3個保存在數(shù)據(jù)庫中的Account實體類型的實例。不會顯示通過 ExecuteSqlCommand() 方法插入的數(shù)據(jù)。以下輸出驗證了這一結(jié)論:
帳戶 ID = 2320
帳戶 ID = 2502
帳戶 ID = 2603
這篇文章到此結(jié)束,我們將在下一篇文章中開始TPH。
實體框架交流QQ群:458326058,歡迎有興趣的朋友加入交流
感謝您的持續(xù)關(guān)注,我的博客地址:
相關(guān)閱讀Relate
熱門文章 Recent
- 語文文言文翻譯模板 高中語文文言文翻譯:怎么整理高中語文課本上的文言文?2023-03-11
- 英語推薦信翻譯模板 關(guān)于英語自我推薦信范文2023-03-11
- 兼職翻譯服務(wù)合同范本模板 兼職翻譯服務(wù)合同樣本2023-03-11
- 內(nèi)部翻譯模板 【*新】外貿(mào)翻譯類個人簡歷模板大全-word范文模板 (3頁)2023-03-11
- 菲律賓駕照翻譯件模板 國外駕駛證翻譯可以自己翻譯嗎2023-03-11
- 留學生畢業(yè)證翻譯模板 留學生落戶上海,上海人才市場要求的畢業(yè)證/學位證、成績單哪里翻譯?2023-03-11
- 商務(wù)信函翻譯模板 商務(wù)英語翻譯基礎(chǔ)ppt模板2023-03-11
- 西班牙簽證房產(chǎn)證翻譯模板 西班牙簽證的翻譯件可以自己準備么2023-03-11
- 韓國駕照換中國駕照翻譯模板 韓國考駕照很簡單?駕考規(guī)則及常見誤區(qū)告訴你2023-03-11
- 加拿大簽證戶口本翻譯模板 請問加拿大學生簽證戶口本要翻譯為英文嗎?2023-03-11