建模多态关联数据库
我们有一个数据库,其中一个表包含的记录可以是其他几个表的子记录。 它有一个“软”外键,由所有者的ID和一个表名组成。 这种(反)模式被称为“多态关联”。 我们知道这不是最好的数据库设计,我们会在适当的时候改变它,但不会在不久的将来。 让我展示一个简化的例子:
Event
, Person
和Product
在评论中都有记录。 正如你所看到的,没有硬性的FK限制。
在实体框架中,可以通过将Comment
到EventComment
等来支持此模型,并让Event
具有EventComments
集合等。
在从数据库生成基本模型后,手动添加子类和关联。 OwnerCode
是此TPH模型中的鉴别器。 请注意Event
, Person
和Product
是完全不同的实体。 为他们建立一个共同的基类是没有意义的。
这是数据库优先。 我们的现实生活模式是这样的,没问题。
好。 现在我们要转向代码优先。 因此,我开始将数据库逆向工程化为代码优先模型(EF Power Tools),并继续创建子类并映射关联和继承。 试图连接到Linqpad的模型。 那时麻烦就开始了。
当试图用这个模型执行一个查询时,它会抛出一个InvalidOperationExeception
外键组件'OwnerId'不是'EventComment'类型的声明属性。 验证它没有被明确地从模型中排除,并且它是一个有效的基本属性。
发生这种情况时,我有双向关联和OwnerId
被映射为Comment
的属性。 我的EventMap
类( EntityTypeConfiguration<Event>
)中的映射如下所示:
this.HasMany(x => x.Comments).WithRequired(c => c.Event)
.HasForeignKey(c => c.OwnerId);
所以我试图在模型中映射没有OwnerId
的关联:
this.HasMany(x => x.Comments).WithRequired().Map(m => m.MapKey("OwnerId"));
这抛出一个MetaDataException
指定的模式无效。 错误:(10,6):错误0019:类型中的每个属性名称必须是唯一的。 属性名称'OwnerId'已经定义。 (11,6):错误0019:类型中的每个属性名称必须是唯一的。 属性名称'OwnerId'已经定义。
如果我删除三个实体评论关联中的两个,那么确定,但这当然不是治愈。
一些更多细节:
EdmxWriter
)时,关联看起来在存储模型中,而在原始的edmx中,它们是概念模型的一部分。 那么,我该如何创建这个模型代码? 我认为关键是如何指示代码优先来映射概念模型中的关联,而不是存储模型。
在任何这种复杂程度的架构上使用EF时,我个人会首先坚持使用数据库。 我首先遇到了有关代码复杂模式的问题。 也许新版本更好一些,但担心如何尝试和编写复杂的关系似乎不太直接,然后让引擎为你生成它。 另外,当关系变得复杂时,我倾向于避免尝试使用EF生成它,并尝试使用存储过程来更轻松地排查可能出现的性能瓶颈。
链接地址: http://www.djcxy.com/p/90213.html上一篇: Modelling polymorphic associations database
下一篇: Is it possible to generate an EF data model (edmx) from code first POCO classes?