我有一個基礎Employee實體和特定僱員類型的一些派生實體的繼承層次結構。我需要能夠將基礎Employee實體轉換爲更具體的實體(例如TemporaryEmployee),並從更具體的類型轉換回基本類型(例如,如果員工不再是「臨時」的,那麼我希望該實例只是持久化爲Employee 在數據庫中,這只是從表中爲特定子類添加或刪除一行的問題(我使用的是每個類的表)。但是我沒有看到如何使用EF調用來完成此操作更改屬於繼承層次結構一部分的(實體框架)實體的類型
回答
從技術上講,您可以通過使用存儲過程來實現它。 TPT不支持它。
但是,我完全同意克雷格。在經典的編程書籍設計模式(Addison-Wesley Professional)中,作者討論了繼承與構圖,並得出結論認爲應該「贊成構圖而不是繼承」。
OOP的原理之一是實例不能改變它們的類型。想一下:你可以用普通的.NET對象來做這件事嗎?當然不是。堅持他們與EF,要麼
向數據庫添加一行不會改變實例的typ e,要麼;它只是EF的謊言,關於你保存的東西。在關係域中,您添加了一個關係,而不是更改對象的類,因爲關係域不知道對象。
因此,長期和短的是,使用EF不會改變.NET規則,即實例不能改變它們的類型。
當你需要這樣做時,你應該怎麼做?那麼,想想這是如何工作在你的問題領域。員工是一個人。他們的就業狀況與該人有關,但他們的身份實際上並不是人。
使用組合而不是繼承。我可能會將此模型設置爲Person,並帶有一系列Employment實例。當一個人的就業情況發生變化時,您可以將停止/終止日期分配給舊記錄,併爲新作業添加新記錄。
我碰巧讀了this blog post今天早上,這可能是進一步的思考。
編輯爲添加如果您通過實施DB存儲過程來解決此問題,請確保沒有人在執行時實際使用系統。因爲這在.NET對象空間中是完全非法的,所以實體框架認爲它不可能發生。如果您繞開實體框架並執行此操作,並且用戶碰巧有一個活動的ObjectContext,則此實體框架中的正常樂觀併發保護未檢測到此ObjectContext與數據庫不同步。您不會損壞數據,但具有活動ObjectContext的用戶可能會看到一些令人難以置信的奇怪錯誤。
好評。繼承在這裏似乎更自然,因爲它允許我定義更具體的類型之間的關係。 是的,你也鏈接到有趣的博客文章 - 將實體更改爲基本類型是一種刪除形式 - 也許我不應該這樣做...... – 2009-09-01 20:53:27
關於您添加的編輯:EF不會並且不能假設它是更新數據庫的唯一過程。事實上,在大多數情況下,它不是 - 您可能至少有多個ObjectContext實例針對同一個數據庫(例如,在Web應用程序中每個用戶一個)運行。 – 2009-09-02 15:56:58
我沒有說EF假定它是更新數據庫的唯一過程,因爲那是錯誤的。我說,當某些外部進程「損壞」數據庫時,它會返回奇怪的錯誤消息。考慮到很多原因,EF考慮將實例的類型改爲腐敗。這只是一個問題,如果(1)與內存中的對象存在活動對象上下文,則(2)其他用戶「改變類型」,然後(3)原始上下文對對象執行某些操作。 EF將檢測到問題並返回高度技術性錯誤。就像我說的那樣,這樣做並不是多用戶安全的。 – 2009-09-02 16:23:38
- 1. 每個層次結構繼承的實體框架表問題
- 2. 每個層次結構實體框架表繼承
- 3. 實體框架4 CTP5 TPT繼承不適用於深層次結構?
- 4. 實體框架中的表繼續層次結構7
- 5. 實體框架:繼承,更改對象類型
- 6. 實體框架的分層架構
- 7. 實體框架繼承
- 8. 實體框架 - 繼承
- 9. 實體框架4 - 繼承
- 10. 實體框架 - 繼承
- 11. 實體框架繼承
- 12. 實體框架和繼承
- 13. 實體框架繼承InverseProperty
- 14. 實體框架4部分的類繼承
- 15. 實體框架中的類和接口層次結構?
- 16. 擴展(繼承)實體框架類(不使用部分)
- 17. 實體框架繼承:按類型排序/分組?
- 18. 如何確定使用實體框架4繼承的實體的子類型?
- 19. 實體框架的繼承問題(每種類型的表)
- 20. 實體框架中的複雜繼承
- 21. 實體框架中的POCO繼承
- 22. 實體框架中的接口繼承
- 23. 實體框架中的繼承 - 每個具體類的表?
- 24. 實體框架中的POCO實體的繼承4
- 25. 實體框架中的層次結構ID不起作用
- 26. 無法保存實體框架繼承的類型
- 27. 手動設置實體框架的表類型繼承
- 28. 具有繼承權限的接入實體框架實體
- 29. 新實體繼承中的實體框架問題
- 30. 分層體系結構中的ASP.NET和實體框架 - 僅針對ORM使用實體框架
是的,現在我已經使用存儲過程實現了這一點。 這也是MSFT的建議: 「你不能直接在實體框架中這樣做,你最好的選擇是編寫存儲過程來完成這些轉換」 http://social.msdn.microsoft.com/Forums/ EN-US/adodotnetentityframework /線程/ 860d7913-7baa-43e9-a2a7-83b25ad9c558 / – 2009-09-01 20:55:45