实体框架导航属性接口类型

4
我正在使用Entity Framework Code-First创建一个应用程序,但是在遵循接口分离原则时,我遇到了EF的一些限制问题。 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; }
}

问题在于“Processes”和“Lines”属性,因为它无法确定具体类型中的哪个类(我想是这样的)。

我知道我可以通过使用抽象类实现几乎相同的功能。我之所以没有这样做的原因是,我发现由于EF的限制而改变模型是不正确的。

有什么解决方法最好?是否有其他替代EF的方法,允许用接口作为导航属性。


我想EF需要知道一个具体的类型来实例化从数据库获取的实体。 - Kralizek
是的。现在我从这里开始做什么? :) - brianfroelund
2个回答

3

只有一种方法可以解决这个问题——使用持久化到数据库的具体类。EF 不支持其他方式。即使使用抽象类也无济于事,除非您映射整个继承树(不要这样做)。

如果您想要公开一个接口属性,您必须提供第二个未映射的属性,该属性将在内部从公开具体类型的属性进行转换。

简单地说,如果您想要使用 EF,您必须调整架构以遵循其功能集。


那么我实际需要使用多态的地方怎么办?如果我坚持使用实体框架,我将被迫为某些部分使用抽象类。如果我选择使用NHibernate,我会面临同样的问题吗? - brianfroelund
如果您需要使用多态性,您将拥有抽象类的多个实现,这种情况下您将不得不映射继承。从您的模型中并不清楚您是否有多个接口实现。我认为NHibernate支持接口。 - Ladislav Mrnka
这是一个部分模型,因为整个东西相当大。感谢您的快速回答! - 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 接口放在我的模型项目中,因为它持有具体实现。这意味着我无法从任何实现接口而不是具体类型的地方访问过程和行,但在我的情况下,这解决了我的问题。

另一种前进的方式是使用 DTO。

您的模型都将使用接口,但您的实际 EF 实现将使用具体的 DTO,在数据层中,您将手动或使用 Automapper 进行映射 - 当然,这可能会对性能产生轻微影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接