問題html
你想從一個已存在的模型中的實體派生一個新的實體,容許基類被實例化。數據庫
解決方案架構
假設你有如圖6-20所示的模型。app
圖6-20 包含Invoice實體的模型框架
這個模型只包含一個單獨的實體Invoice(發貨單)。咱們想從Invoice派生一個新的實體,它表示刪除掉的發貨單。這將容許咱們以更清晰的業務邏輯來分別對有效的發貨單和已刪除掉的發貨進行不一樣的操做。按下面的步驟,添加這個派生類型:學習
一、在Mapping Details window(映射詳細信息窗口)查看實體Invoice的信息,在IsDeleted列上添加一個條件,When IsDeleted =0(當IsDeleted列值爲0),如圖6-21所示。spa
圖6-21 當IsDeleted列爲0時映射Invoice實體翻譯
二、如今IsDeleted列被用做條件,咱們須要將其從實體的標量屬性中移除。在實體Invoice的屬性IsDeleted上右鍵,選擇Delete(刪除);設計
三、右鍵設計器,並選擇Add(新增)➤Entity(實體)。命名新實體爲DeletedInvoice,並選擇Invoice做爲基類;3d
四、在Mapping Details window(映射詳細信息窗口),查看實體DeletedInvoice的映射信息。將它映射到Invoice表,在IsDeleted列上添加一個條件,When IsDeleted =1(當IsDeleted列值爲1),如圖6-22所示。
圖6-22 當IsDeleted列爲1時映射DeletedInvoice實體
包含Invoice實體和派生類型DeletedInvoice實體的最終模型,如圖6-23所示。
圖6-23 包含實體Invoice和DeletedInvoice的概念模型
原理
有兩種不一樣的方式能夠對咱們的Invoice和DeletedInvoice建模。咱們演示的這種方法,只是在以下狀況下推薦使用,你有一個已經存在的模型和代碼庫,你想添加派生類型實體DeletedInvoice, 並對已有代碼產生儘可能少的影響。對於一個新模型,從基類Invoice派生一個ActiveInvoice類型和一個DeleteInvoice類型會更好。若是選擇後面這種方法,你須要將基類標記爲抽象類型。
這裏使用咱們演示的這種方式,正如代碼清單6-37所展現的那樣,你能夠決定,是選擇casting仍是OfType<>()方法來轉換DeletedInvoice。可是,你不能單獨select實體Invoice,這是這個方法最大的缺點。
代碼清單6-37.使用as操做符來判斷咱們擁有的是一個Invoice類型仍是DeletedInvoice類型
1 using (var context = new Recipe13Context()) 2 { 3 context.Invoices.Add(new Invoice 4 { 5 Amount = 19.95M, 6 Description = "Oil Change", 7 Date = DateTime.Parse("4/11/13") 8 }); 9 context.Invoices.Add(new Invoice 10 { 11 Amount = 129.95M, 12 Description = "Wheel Alignment", 13 Date = DateTime.Parse("4/01/13") 14 }); 15 context.Invoices.Add(new DeletedInvoice 16 { 17 Amount = 39.95M, 18 Description = "Engine Diagnosis", 19 Date = DateTime.Parse("4/01/13") 20 }); 21 context.SaveChanges(); 22 } 23 24 using (var context = new Recipe13Context()) 25 { 26 foreach (var invoice in context.Invoices) 27 { 28 var isDeleted = invoice as DeletedInvoice; 29 Console.WriteLine("{0} Invoice", 30 isDeleted == null ? "Active" : "Deleted"); 31 Console.WriteLine("Description: {0}", invoice.Description); 32 Console.WriteLine("Amount: {0:C}", invoice.Amount); 33 Console.WriteLine("Date: {0}", invoice.Date.ToShortDateString()); 34 Console.WriteLine(); 35 } 36 }
代碼清單6-37的輸出以下:
Active Invoice Description: Oil Change Amount: $19.95 Date: 4/11/2013 Active Invoice Description: Wheel Alignment Amount: $129.95 Date: 4/1/2013 Deleted Invoice Description: Engine Diagnosis Amount: $39.95 Date: 4/1/2013
問題
你想使用Model First來建立獨立關聯和外鍵關聯。
解決方案
獨立關聯和外鍵關聯幫助咱們在數據庫架構內維護引用完整性,並提供指向關聯實體的導航路徑。爲了使用Model First建立外鍵和獨立關聯,請按下面的步驟操做:
一、在你的項目中添加一新個ADO.NET Entity Data Model(ADO.NET實體數據模型),在提示選擇模型內容時選擇空模型,單擊完成。這將建立一個空的計設界面;
二、右鍵設計器,並選擇Add(新增)➤Entity(實體)。命名新實體爲User,並單擊OK(肯定);
三、右鍵新添加的實體,爲其添加一個標量屬性UserName;
四、右鍵設計器,並選擇Add(新增)➤Entity(實體)。命名新實體爲PassordHistory,並單擊OK(肯定);
五、右鍵新添加的實體,爲其添加一個標量屬性LastLogin。右鍵LastLogin,改變其類型爲DateTime;
六、右鍵實體User,選擇Add(增長) ➤Association(關聯)。建立外鍵關聯,勾選Add froreign key properties to the PasswordHistory Entity(向「PassordHistory」實體中添加外鍵屬性)複選框; 建立獨立關聯,就不要勾選。
七、右鍵設計器,並選擇Generate Model from Database(從數據庫生成模型)。選擇一個數據庫鏈接,並完成接下來的嚮導。這將產生模型的存儲層和映射層,並生成一個從模型生成 數據庫的腳本。
若是你選擇建立一個外鍵關聯,模型如圖6-24所示。若是選擇建立一個獨立關聯,模型如圖6-25所示。
圖6-24. User和PasswordHistory之間的外鍵關聯
圖6-25. User和PasswordHistory之間的獨立關聯
原理
對於一個外鍵關聯,外鍵被看成依賴實體的一個屬性。暴露外鍵容許使用與管理別的屬性值相同的代碼,來管理關聯的不少方面。最主要的幫助就是在離線場景,咱們將會在第九章看到相關的內容。外鍵關聯是實體模型的默認行爲。
對於獨立關聯,外鍵不會做爲依賴實體的屬性。這使得模型的概念層有幾分清爽,由於這裏沒有引入關聯的實現細節這種噪音。在早期的實體框架版本中只支持獨立關聯。
問題
你一個使用獨立關聯的模型,你想把獨立關聯改變成一個外鍵關聯。
解決方案
假設你有如圖6-26所示的模型。
圖6-26. vehicles和tickets 間使用獨立關聯的模型
按下面的步驟修改一個獨立關聯爲外鍵關聯:
一、右鍵Ticket實體,選擇Add(新增) ➤Scalar Property(標量屬性)。並重命名爲LicenseNumber(牌照號碼);
二、在Mapping Details window(映射詳細信息窗口)中查看關聯的映射信息,從映射到Ticket控件中選擇 <Delete>,移除Ticket表的映射;
三、右鍵關聯,查看properties(屬性),單擊引用約束控制按鈕,在彈出的對話框中,在Principal(主體)下拉菜單中選擇Vehicle。Principal Key(主體鍵)和Dependent Property(依賴屬性)均設置爲LicenseNumber,如圖6-27所示。
圖6-27. 爲外鍵關聯建立引用約束
四、在Mapping Details window(映射詳細信息窗口)中查看實體Ticket的映射信息,映射列LicenseNumber到屬性LicenseNumber,如圖6-28所示。
圖6-28. 爲實體ticket映射LicenseNumber屬性到LicenseNumber列
最終的模型如圖6-29所示。
圖6-29. 獨立關聯修改成外鍵關聯的模型
原理
當你把獨立關聯修改爲外鍵關聯後,你已存在的絕大多數代碼是能夠正常運行的。你會發現,如今關聯兩個實體變得很是簡單了,只需給外鍵屬性設置合適的值 。在獨立關聯中改變一個關係,你須要爲實體鍵建立一個新的實例,並設置實體的xxxReference.EntityKey爲這個新的實例。在外鍵關聯中,你只須要簡單地設置外鍵屬性的值爲主鍵值。
外鍵關聯目前不支持多對多關聯,由於這些關聯必須被映射到底層的連接表。也許,在未來的實體框架的版本中,外鍵關聯,經過附帶載荷來支持多對多關聯。
至此,第六章結束,下篇咱們將進入第七章,本篇有點長,感謝你的閱讀!
實體框架交流QQ羣: 458326058,歡迎有興趣的朋友加入一塊兒交流
謝謝你們的持續關注,個人博客地址:http://www.cnblogs.com/VolcanoCloud/