我在閱讀有關實體框架4.0,我想知道爲什麼我應該創建一個複雜的類型,而不是一個新的實體(表)和它們之間的關係?實體框架複雜類型vs創建新實體
回答
完美的例子是一個地址。使用複雜類型的地址比新實體更容易處理。對於複雜類型,您不必處理主鍵。考慮訪問地址有多少種常見類型的實體會有地址(業務單位,人員,地點)。想象一下,填充許多人的地址並需要爲每個人設置一個密鑰。對於複雜的類型,只需訪問它們的內部屬性即可完成。這是一個示例的MSDN鏈接。 http://msdn.microsoft.com/en-us/library/bb738613.aspx
基於域驅動設計概念,聚合根可以有一個或多個內部對象作爲其部分。在這種情況下,內部對象 - 在Aggregate Root的邊界內 - 沒有任何KEY。父鍵將應用於它們或以某種方式如此。您的答案返回到保持聚合根內所有零件的好處,使您的模型更健壯,更簡單。
聚合根可能包含具有密鑰的實體。他們只屬於一個聚合根。 – 2015-03-28 11:18:54
這個問題已經出現了一段時間了,但我仍然會添加一個答案,希望隨之而來的下一個可憐的哭泣知道他在做什麼。
複雜類型不支持延遲加載,至少在EF 4.3中不支持延遲加載。我們以地址情況爲例。你有一個有15列的Person表,其中5個包含某些個人的地址信息。它有5萬條記錄。您爲具有複雜類型Address的表創建實體Person。
如果您需要在數據庫中的所有個人的名單,你會做
var records = context.Persons;
其中還包括地址,抽5個* 50K值到你的列表中沒有任何理由,並用明顯的延遲。你可以選擇只加載您在一個匿名類型需要
var records = from p in context.Persons
select new {
LastName = p.LastName,
FirstName = p.FirstName,
}
這對於這種情況下行之有效的值,但是如果你需要使用,也就是說,8個非地址欄一個更全面的列表,你要麼需要在匿名類型中添加每一個,或只是與第一個案例一起,並返回加載無用的地址數據。
這是關於匿名類型的事情:雖然它們在單個方法中非常有用,但它們強制您在類或子類的其他地方使用動態變量,這會取消Visual Studio的某些重構工具並讓您打開運行時間錯誤。理想情況下,您希望在您的方法中分發實體,以便這些實體儘可能少地攜帶行李。這就是爲什麼懶加載非常重要。
說到上面的例子,地址信息應該真正在它自己的表中,並且有一個完整的實體覆蓋它。作爲一個附帶好處,如果您的客戶要求第二個人的地址,您可以通過在Person中添加額外的地址引用將其添加到您的模型中。
如果不像上面的例子,你幾乎在每個查詢中都需要地址數據,並且真的想在Person表中有這些字段,那麼只需將它們添加到Person實體即可。你將不再擁有整潔的地址前綴,但它不完全是失去睡眠的東西。
但是等等,還有更多!
複雜類型是一種特殊情況,是普通EF實體平滑景觀中的顛簸。你項目中的那些人可能沒有資格從你的實體基類繼承,這使得他們不可能通過處理你的實體的方法來處理它們。
假設您有一個名爲EntityModel的實體基類,它定義了一個屬性ID。這是你的所有實體對象的關鍵,所以您現在可以創建
class EntityModelComparer<T> : IEqualityComparer<T> where T : EntityModel
,你可以再從類型T的任何IQueryable的其中T是實體類鮮明的()來過濾重複使用。複合類型不能從EntityModel繼承,因爲它沒有ID屬性,但這很好,因爲無論如何你都不會使用獨特的。
更進一步,您遇到了一種情況,您需要某種方式來通過任何實體並執行操作。也許你想要在UI上動態列出一個實體的屬性,並讓用戶對它們執行查詢。所以你構建一個類可以實例化的特定類型,並將它採取了整個事情的護理:
public class GenericModelFilter<T> : where T : EntityModel
哦,等一下,你的複雜類型的類型EntityModel的不是。現在,您必須將實體繼承樹複雜化以適應複雜類型或擺脫EntityModel合同並降低可見性。
一起移動,添加,基於用戶選擇你的類中的方法可以創建,你可以使用LINQ用於過濾任何實體類
Expression<Func<T, bool>> GetPredicate() { ... }
所以現在你可以做這樣的事情的表達式:
personFilter = new GenericModelFilter<Person>();
companyFilter = new GenericModelFilter<Company>();
addressFilter = new GenericModelFilter<Address>(); //Complex type for Person
...
var query = from p in context.Persons.Where(personFilter.GetPredicate())
join c in context.Companies.Where(companyFilter.GetPredicate()) on p.CompanyID = c.ID
select p;
這對所有實體對象都是一樣的......除了有特殊需求的地址。你不能像對待公司一樣爲它加入。你可以從Person導航到它,但是你如何將它應用到它上面,最後還是Person?現在你必須花點時間想出一個簡單的系統,這個系統在其他地方很容易運行。
該模式在項目的整個生命週期中都會重複出現。我是否根據經驗說話?我希望我沒有。複雜的類型會阻止你的進步,就像班級背後的一個行爲不端的學生一樣,不會增加任何內容。自己幫忙,選擇實際的實體對象。
- 1. 實體框架:存儲複雜類型
- 2. 實體框架EF4複雜類型
- 3. 實體框架5複雜類型
- 4. 實體框架 - 重用複雜類型
- 5. 實體框架5.0複雜類型
- 6. 實體框架中的複雜類型
- 7. 實體框架5種複雜類型
- 8. 實體框架嵌套複雜類型
- 9. 實體框架創建重複實體
- 10. 實體框架重新創建POCO類
- 11. 如何獲取實體框架來更新複雜類型?
- 12. 使用實體框架更新複雜數據實體
- 13. ADO.NET實體框架 - 輕鬆重新創建實體類?
- 14. 實體框架4.0。實體創建
- 15. 實體框架 - 自動生成vs手動創建實體
- 16. 實體框架 - 如何爲實體類創建基類?
- 17. 實體框架無法正確創建從MySql存儲的複雜類型
- 18. 實體框架不爲我的存儲過程創建複雜類型?
- 19. 創建複合關鍵實體框架
- 20. 實體框架5:創建
- 21. 複雜的實體框架加入
- 22. 複雜的實體框架查詢
- 23. 實體框架4.1複雜POCOs
- 24. 實體框架的複雜關係
- 25. 實體框架中的複雜繼承
- 26. 實體框架 - 刪除複雜對象
- 27. 實體框架複雜LINQ支持
- 28. 複雜的實體框架查詢
- 29. 複雜Sql的實體框架查詢
- 30. 實體框架複雜查詢
擁有複雜類型而不是普通標量屬性有什麼好處? – emzero 2010-04-29 01:01:10
@emzero我猜他們很多,這基本上是一個OOD。您可能不想在發送貨件時在地址上定義get方法或將地址對象傳遞給某些其他方法。它也遵循DRY方法。假設你做了一個ToString()覆蓋,你只需要爲所有具有Address的類執行一次。 – 2012-04-13 15:07:08
這難道不會讓所有不同的表的所有地址都難以執行操作嗎?如果我想添加地理位置數據,或者清理所有地址格式等?用這張獨立的桌子,這不是很容易嗎?或者你可以做一些像 repo.ComplexTypes.ToList() – 2013-03-18 08:52:00