8表翻譯模板 2-8 Table per Type Inheritance 建模
日期:2023-03-11 12:39:36 / 人氣: 772 / 發(fā)布者:成都翻譯公司
2、使用代碼清單2-16創(chuàng)建一個(gè)POCO實(shí)體Business;代碼清單2-19的輸出如下:按下面的步驟,為表Account建模,模型中實(shí)體類(lèi)型只代表激活狀態(tài)的賬戶代碼清單2-20演示了從Account表插入和獲取數(shù)據(jù)。之所有這樣做,是因?yàn)槲覀冃枰迦胍恍蠨eletedOn列為非null值的數(shù)據(jù)。翻譯的初衷以及為什么選擇《Entity Framework 6 Recipes》來(lái)學(xué)習(xí),請(qǐng)看本系列開(kāi)頭
2-8 每個(gè)類(lèi)型繼承建模的表
問(wèn)題
您有這樣一個(gè)數(shù)據(jù)庫(kù)表,其中包含一些附加信息,這些信息屬于公共表。您想使用 Table per Type Inheritance (TPT) 繼承映射建模。
解決方案
假設(shè)您有兩個(gè)與公共表密切相關(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 對(duì)這種繼承進(jìn)行建模(零售和電子商務(wù)實(shí)體從業(yè)務(wù)實(shí)體繼承)。
1、 在你的項(xiàng)目中創(chuàng)建一個(gè)繼承自 DbContext 的上下文對(duì)象 EF6RecipesContext;
2、 使用代碼清單2-16創(chuàng)建POCO實(shí)體Business;
代碼清單2-16 創(chuàng)建POCO實(shí)體業(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)建一個(gè)POCO實(shí)體eCommerce,它繼承自Business類(lèi)
代碼清單 2-17 創(chuàng)建 POCO 實(shí)體 eCommerce
1 [Table("eCommerce", Schema = "Chapter2")] 2 public class eCommerce : Business { 3 public string URL { get; set; } 4 }
4、 使用代碼清單2-18創(chuàng)建一個(gè)POCO實(shí)體Retail,它繼承到Business類(lèi)
代碼清單 2-18 創(chuàng)建 POCO 實(shí)體零售
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.給上下文對(duì)象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ū)ο缶幊讨校覀冇幸粋€(gè)基類(lèi) Business 和兩個(gè)派生類(lèi),Retail 和 eCommerce。
由于1:0...1的關(guān)系,在Retail和eCommerce表中,不可能有表Business中沒(méi)有對(duì)應(yīng)行的數(shù)據(jù)(行)。在面向?qū)ο笾校缮?lèi)繼承基類(lèi)的屬性,是繼承的核心。在每個(gè)類(lèi)型的表(通常稱為 TPT)映射中,每個(gè)派生類(lèi)都表示為一個(gè)單獨(dú)的表。
代碼清單 2-19 演示了從模型中插入和獲取
代碼清單2-19 在TPT模型中插入和獲取實(shí)體
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í)體的一個(gè)實(shí)例和兩個(gè)派生類(lèi)的實(shí)例。使用上下文中設(shè)置的業(yè)務(wù)實(shí)體中的 Add() 方法將它們添加到上下文中。
在查詢中,我們迭代上下文中設(shè)置的 Businesses 實(shí)體以訪問(wèn)所有業(yè)務(wù)。對(duì)于派生類(lèi)型,我們使用泛型方法 OfType() 并通過(guò)指定特定類(lèi)型參數(shù)在實(shí)體集中進(jìn)行過(guò)濾。
代碼清單2-19的輸出如下:
--- 所有企業(yè) --- 角落干洗 (#100X1)
購(gòu)物省錢(qián) (#200C)
(#300AB)
--- 零售業(yè)務(wù) --- 購(gòu)物省錢(qián) (#200C)
101 主
Anytown,德克薩斯州 76106
---- 電子商務(wù)企業(yè) (#300AB)
網(wǎng)上地址是:
TPT 是實(shí)體框架支持的三種繼承映射之一。另外兩個(gè)是 Table per Hierarchy(TPH,將在本章后面討論)和 Table per Concrete Type(TPC,見(jiàn)第 15 章)。
TPT 繼承映射為數(shù)據(jù)庫(kù)提供了靈活性。作為開(kāi)發(fā)人員,我們可以輕松地為模型中新添加的表添加派生類(lèi)型。但是,每個(gè)派生類(lèi)型都會(huì)涉及一個(gè)額外的連接連接,這會(huì)降低系統(tǒng)的性能。在實(shí)際應(yīng)用中,我們已經(jīng)看到了派生類(lèi)型較多時(shí)使用TPT繼承映射導(dǎo)致的性能問(wèn)題。
每層級(jí)表 (TPH) 繼承映射將在第 2-10 節(jié)中描述。它將整個(gè)繼承類(lèi)型存儲(chǔ)在單獨(dú)的表中。解決了TPT中的join連接問(wèn)題,帶來(lái)了不錯(cuò)的性能。但以犧牲數(shù)據(jù)庫(kù)的靈活性為代價(jià)。
每個(gè)具體的表 (TPC) 繼承映射,它在運(yùn)行時(shí)由實(shí)體框架支持,但由設(shè)計(jì)器不支持。TPC 的重要應(yīng)用見(jiàn)第 15 章。
2-9 使用條件過(guò)濾對(duì)象集
問(wèn)題
您想在實(shí)體類(lèi)型上創(chuàng)建固定條件以映射表中行的子集。
解決方案
假設(shè)您有一個(gè)包含帳戶信息的數(shù)據(jù)庫(kù)表,如圖 2-18 所示。該表有一個(gè)可以為空的列 DeletedOn,用于存儲(chǔ)帳戶被刪除的日期和時(shí)間。如果賬戶被激活,列DeletedOn的值為空,并且你希望實(shí)體類(lèi)型只代表激活的賬戶,即沒(méi)有DeletedOn值的賬戶。
圖 2-18 帶有 DeletedOn 列表的 Account 表
按照以下步驟為表 Account 建模。模型中的實(shí)體類(lèi)型僅代表活躍賬戶
1、 右鍵單擊??您的項(xiàng)目,選擇 Add ?New Item8表翻譯模板,然后在 Visual C# 條目下的 Data 模板下選擇 ADO.NET Entity Data Model。
2、選擇從數(shù)據(jù)庫(kù)生成以從現(xiàn)有數(shù)據(jù)庫(kù)創(chuàng)建模型,然后單擊下一步。
3、您可以選擇一個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)連接,也可以選擇創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)連接。
4、 在選擇數(shù)據(jù)庫(kù)窗口中,選擇表帳戶。然后選中復(fù)選框以確定生成的對(duì)象名稱的單數(shù)和復(fù)數(shù)形式,并在模型中包含外鍵列。單擊完成
5、 如果未顯示映射詳細(xì)信息窗口,則單擊帳戶實(shí)體并查看映射詳細(xì)信息窗口。選擇工具菜單查看(查看)? 其他窗口(其他窗口)? 實(shí)體數(shù)據(jù)模型映射詳細(xì)信息(實(shí)體數(shù)據(jù)模型映射詳細(xì)信息)。單擊映射詳細(xì)信息窗口中的添加條件8表翻譯模板,然后選擇列 DeletedOn,在運(yùn)算符列中,選擇是,在值/屬性列中,選擇空。這是它創(chuàng)建了一個(gè)映射條件(圖2-18)
6、 右擊DeletedOn 屬性,選擇Delete,因?yàn)槲覀兪褂昧蠨eletedOn 作為條件映射,所以不映射到實(shí)體中的屬性。在我們的模型中,它的值始終為 Null。
原則
在示例中,我們?cè)趯?shí)體 Account 中應(yīng)用 Is Null 條件來(lái)過(guò)濾 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)用上下文對(duì)象的Database屬性中的ExecuteSqlCommand()方法向數(shù)據(jù)庫(kù)中插入一行數(shù)據(jù)。這一切都是因?yàn)槲覀冃枰?DeletedOn 列中插入一行非空值的數(shù)據(jù)。在模型中,Account 實(shí)體沒(méi)有映射此列的屬性。實(shí)際上,Account 實(shí)體不可能映射到DeletedOn 列的值的行,而這恰好是我們需要測(cè)試的。
對(duì)于第一部分代碼的其余部分,我們創(chuàng)建并初始化了 Account 實(shí)體類(lèi)型的 3 個(gè)實(shí)例,并通過(guò) SaveChanges() 方法將它們保存到數(shù)據(jù)中。
當(dāng)我們查詢數(shù)據(jù)數(shù)據(jù)庫(kù)時(shí),通過(guò)SaveChanges()方法只能得到3個(gè)保存在數(shù)據(jù)庫(kù)中的Account實(shí)體類(lèi)型的實(shí)例。不會(huì)顯示通過(guò) ExecuteSqlCommand() 方法插入的數(shù)據(jù)。以下輸出驗(yàn)證了這一結(jié)論:
帳戶 ID = 2320
帳戶 ID = 2502
帳戶 ID = 2603
這篇文章到此結(jié)束,我們將在下一篇文章中開(kāi)始TPH。
實(shí)體框架交流QQ群:458326058,歡迎有興趣的朋友加入交流
感謝您的持續(xù)關(guān)注,我的博客地址:
相關(guān)閱讀Relate
熱門(mén)文章 Recent
- 英語(yǔ)祝賀信模板及翻譯 感謝信英語(yǔ)作文模板(感謝老師的英文作文)2023-03-11
- 翻譯的模板鏈 客戶關(guān)系管理價(jià)值鏈研究模板.doc2023-03-11
- 醫(yī)學(xué)出生證明德語(yǔ)翻譯模板 美國(guó)路易斯安那州出生證明翻譯蓋章丨上海正規(guī)翻譯公司2023-03-11
- 商品房購(gòu)銷(xiāo)合同翻譯模板 商品房買(mǎi)賣(mài)合同樣本2023-03-11
- 翻譯項(xiàng)目證明模板 南開(kāi)大學(xué)本科生成績(jī)單、在讀證明及各類(lèi)證書(shū)翻譯件辦理流程須知(2018年10月修訂2023-03-11
- 營(yíng)業(yè)執(zhí)照副本復(fù)印件翻譯模板 工商營(yíng)業(yè)執(zhí)照翻譯2023-03-11
- 英文證書(shū)翻譯模板 畢業(yè)證書(shū)英文翻譯模板.doc2023-03-11
- 居住登記憑證翻譯模板 長(zhǎng)沙居住登記憑證辦理指南(條件+資料+時(shí)間)2023-03-11
- 出生證翻譯模板-戶口本和身份證中英文翻譯模板2023-03-11
- 考研萬(wàn)能英語(yǔ)作文模板及翻譯 考研英語(yǔ)大作文十大萬(wàn)能模板.pdf 6頁(yè)2023-03-11