映射许多:来自多个实体类型的可选关系EF Code First

时间:2012-06-04 13:45:12

标签: entity-framework-4.1 ef-code-first fluent-interface

我们有3个相互关联的实体:

  • Foo有很多附件
  • Bar有很多附件
  • 每个附件都可以属于Foo或Bar。

使用DbModelBuilder对此进行建模的最佳方法是什么?

如果我们尝试:

modelBuilder.Entity<Foo>().HasMany(t => t.Attachments).WithOptional()
    .Map(m => m.MapKey("FOO_ID")).WillCascadeOnDelete(true);
modelBuilder.Entity<Bar>().HasMany(t => t.Attachments).WithOptional()
    .Map(m => m.MapKey("BAR_ID")).WillCascadeOnDelete(true);

这不是一个非常干净的数据模型: * Attachments表将有两个FK列,每个可能的父实体一个('FOO_ID','BAR_ID')。如果我们增加需要附件的实体数量,它会使表格膨胀。 *我们需要使后向引用可选,尽管附件总是附加到实体。它不一定是Foo,也不一定是吧。但是,架构允许将所有FK设置为​​NULL的附件,尽管它在业务视图中无效。 *理论上,一个附件可以链接到Foo和Bar,这是无效的。

相反,我们可能会将关系映射到联结表'T_FOO_ATTACHMENT'和'T_BAR_ATTACHMENT': * T_FOO_ATTACHMENT具有所需的 Foo外键(FOO_ID)和附件所需的FK(ATTACHMENT_ID)。 *同样适用于T_BAR_ATTACHMENT

缺点: *附件仍然可以链接到Foo和Bar。 *附件甚至可以链接到多个Foo,这也是无效的。理想情况下,我们可以使用流畅的语法来添加阻止这种情况的数据库约束。

1 个答案:

答案 0 :(得分:2)

  

这不是一个非常干净的数据模型:附件表将有   两个FK列,每个可能的父实体一个('FOO_ID',   'BAR_ID')。

但从关系角度来看它绝对正确 - 如果你想与另一个表有关系,你需要一个新的外键。

  

但是所有FK设置为​​NULL的附件都将被允许   虽然模式在业务视图中无效,但它仍然有效。理论上一个   附件可以链接到Foo和Bar,而不是   有效的。

这是您的业务逻辑。使用您当前的模型,您必须在您的应用程序中强制执行它。

您正在寻找的是某种命名关系,其中Attachment不仅有FK,还有相关表的名称。这是你在关系层面上无法实现的东西 - 它是数据级别(再次是业务逻辑),不能用EF映射。