4

我使用實體框架代碼優先創建應用程序,並且我在遵循界面分段原則時遇到了EF的侷限性問題。 Part of application model architecture in UML實體框架導航屬性接口類型

public interface IProduct 
{ 
    int Id { get; set; } 
    ICollection<IProcess> Processes { get; set; } 
    ICollection<ILine> Lines { get; set; } 
    String Description { get; set; } 
    String Number { get; set; } 
    String Name { get; set; } 
} 

問題是在進程和Lines屬性導致它不能找出哪個類的具體類型(I假定)。

我知道我可以通過使用抽象類達到幾乎相同。我之所以沒有這麼做,是因爲EF限制,我發現改變模型是錯誤的。

什麼是解決此問題的最佳方法? EF允許接口作爲導航屬性的任何替代方法。

+0

我想EF在實現它從數據庫中獲得的實體時需要知道具體類型來實例化 – Kralizek

+0

是的。現在我從這裏做什麼? :) – brianfroelund

回答

3

只有一種解決方法 - 使用具體的類保存到數據庫中。 EF不支持任何其他方式。即使使用抽象類也不會幫助你,除非你映射整個繼承樹(不要這樣做)。

如果你想要暴露一個接口的屬性,你必須提供第二個非映射屬性,它將在屬性中公佈具體類型的屬性。

簡單地說,如果你想使用EF,你必須彎曲你的架構來遵循它的功能集。

+0

我實際上需要使用多態的地方呢?如果我堅持實體框架,我將被迫爲某些部分使用抽象類。如果我選擇使用NHibernate,我會面臨同樣的問題嗎? – brianfroelund

+0

如果您需要使用多態,您將有多個抽象類的實現,在這種情況下,您將不得不映射繼承。從你的模型中不清楚你有多個接口的實現。我認爲NHibernate支持接口。 –

+0

這是一個部分模型,因爲整個事情都比較大。感謝你及時的答覆! – brianfroelund

0

我知道這是一個古老的線程,但萬一有其他人遇到它,我使用EF有一個稍好的解決方法。

基本上我有兩個接口

public interface IProduct 
{ 
    int Id { get; set; } 
    String Description { get; set; } 
    String Number { get; set; } 
    String Name { get; set; } 
} 

public interface IEFProduct 
{ 
    ICollection<IProcess> Processes { get; set; } 
    ICollection<ILine> Lines { get; set; } 
} 

我把IProduct接口在我的合同項目,因此它仍然是完全獨立於我的模型的休息,但我把IEFProduct我的Model項目中的接口,因爲這包含了具體的實現。這意味着我無法從實現接口的任何東西訪問這些進程和線路,而不是實際的類型,但在我的情況下,它讓我解決了這個問題。

另一種方式是使用DTO。

您的模型都將使用該接口,但是您的實際EF實現將使用混凝土DTO,在數據層中您可以手動或使用Automapper在它們之間進行映射 - 當然這可能會對性能產生輕微影響。