我创建了一个EntityFramework 6数据上下文(代码优先)来表示数据库中的一些表:对于下面引用的repro代码,一个(Items
)包含某种字典的项目,另一个( Notes
)包含一些可以附加到项目的注释。一个项目可以包含0个或多个注释。这里没什么难的:我每桌只有一个POCO对象,这就是我正在做的事情;但是,从我的DbContext
初始化数据库时,我收到错误:
"The entity types 'EfItem' and 'Item' cannot share table 'Item' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them."
现在,对于将多个对象映射到同一SQL表的情况,此错误似乎很有意义,但这不是这种情况。我为每个表都有1个且只有1个具体对象。那么,这个错误的原因可能是什么?
我创建了一个 repro解决方案,您可以从https://1drv.ms/u/s!AMHCfliT740PkK9H下载,需要进一步说明。
此解决方案的要点是我需要保持客户端代码完全不依赖于所选的存储技术,这可能是RDBMS,NoSql DB等。为此,在我的解决方案中,我有一个“核心“项目,一个PCL,其中包含仅处理接口的高级存储库的接口。例如,我有类似AddItem(IItem item)
的方法,而不是直接使用具体类型。
这允许我根据所选技术的需要自定义具体对象:例如,EF对象需要“父”导航属性,而这些在MongoDB中没有意义。当然,这种方法的缺点是必须重新定义大多数具体类型,并将它们转换为它们的接口实现对应物:例如,在EF中我有一个EfItem
对象,可以转换为{{ 1}}。请注意,此对象不实现此接口,但可以简单地转换为它:EF强制我在导航属性中使用具体类型(请参阅例如How to use interface properties with CodeFirst),以便例如项目的IItem
集合在核心项目中的类型为Notes
,但在EF项目中的类型为INote
。
对于EF6项目,我添加了几个POCO对象来表示项目和注释,以及EfNote
派生类,每个类型DbContext
DbSet
,EfItem
{1}})。请注意,这些对象是简单的具体类型,与任何其他具体类型没有直接关系,并且通常甚至不实现相应的核心接口。例如,在核心项目中,我有一个实现EfNote
的{{1}}具体类型,但它完全独立于Item
(IItem
有EfItem
而{{1}有} EfItem
)。没有继承,也没有表拆分; List<EfNote> Notes
映射到SQL表IItem
,List<INote> Notes
映射到EfItem
。
以下是我的EF对象的基本代码:
Item
这是我的EF背景:
EfNote
SQL表定义是:
Note
答案 0 :(得分:2)
在WorkContext.cs
中更改 public DbSet Items {get;组; } 至 public DbSet EFItems {get;组; }
同样在方法保护的覆盖void OnModelCreating(DbModelBuilder mb)
b.Entity()ToTable。(&#34; EFItem&#34);
EF遵循C#class和DB table name之间的一些命名约定,因为你创建了一个名为&#39; Item&#39;的类,我恐怕EF混合类Item和EFItem在一起。