我正在使用实体框架代码创建一个应用程序,并且我在遵循接口分割原则的同时面临着EF的局限性问题。
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; }
}
问题是进程和线属性导致它无法找出具体类型中的哪个类(我推测)。
我知道通过使用抽象类我几乎可以达到相同的效果。我之所以没有这样做的原因是因为EF的限制我改变模型是错误的。
解决这个问题的最佳方法是什么? EF的任何替代方法,允许接口作为导航属性。
答案 0 :(得分:3)
只有一种方法可以解决这个问题 - 使用具体类持久保存到数据库中。 EF不支持任何其他方式。即使使用抽象类也不会帮助你,除非你映射整个继承树(不要这样做)。
如果您希望属性公开接口,则必须提供第二个非映射属性,该属性将从内部公开具体类型的属性进行转换。
如果您想使用EF,您必须弯曲您的架构以遵循其功能集。
答案 1 :(得分: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在它们之间进行映射 - 当然这可能会对性能产生轻微影响。