建模多态关联数据库

我们有一个数据库,其中一个表包含的记录可以是其他几个表的子记录。 它有一个“软”外键,由所有者的ID和一个表名组成。 这种(反)模式被称为“多态关联”。 我们知道这不是最好的数据库设计,我们会在适当的时候改变它,但不会在不久的将来。 让我展示一个简化的例子:

EventPersonProduct在评论中都有记录。 正如你所看到的,没有硬性的FK限制。

在实体框架中,可以通过将CommentEventComment等来支持此模型,并让Event具有EventComments集合等。

在这里输入图像描述

在从数据库生成基本模型后,手动添加子类和关联。 OwnerCode是此TPH模型中的鉴别器。 请注意EventPersonProduct是完全不同的实体。 为他们建立一个共同的基类是没有意义的。

这是数据库优先。 我们的现实生活模式是这样的,没问题。

好。 现在我们要转向代码优先。 因此,我开始将数据库逆向工程化为代码优先模型(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'已经定义。

如果我删除三个实体评论关联中的两个,那么确定,但这当然不是治愈。

一些更多细节:

  • 通过添加一个DbContext生成器项目,可以从edmx创建一个工作的DbContext模型(“code second”)。 (这将暂时解决)。
  • 当我将工作代码优先模型(带有一个关联)导出到edmx( 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?