【问题标题】:Map many:optional relationships from multiple entity types EF CodeFirst映射许多:来自多个实体类型的可选关系 EF Code First
【发布时间】:2012-06-04 13:45:11
【问题描述】:

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

  • Foo 有很多附件
  • 栏有很多附件
  • 每个附件都可以属于 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);

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

相反,我们可以将关系映射到联结表“T_FOO_ATTACHMENT”和“T_BAR_ATTACHMENT”: * T_FOO_ATTACHMENT 有一个 必需 Foo (FOO_ID) 外键和一个必需 FK 到 Attachment (ATTACHMENT_ID)。 * T_BAR_ATTACHMENT 也一样

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

【问题讨论】:

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


    【解决方案1】:

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

    但从关系的角度来看这是绝对正确的——如果你想与另一个表建立关系,你需要一个新的外键。

    但是所有 FK 都设置为 NULL 的附件将被 虽然从业务视图来看它是无效的。理论上一 附件可以链接到 Foo 和 Bar,这不是 有效。

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

    您正在寻找的是某种命名关系,其中Attachment 不仅具有 FK,而且还具有相关表的名称。这是您在关系级别上无法实现的 - 它是数据级别(再次是业务逻辑),并且无法使用 EF 进行映射。

    【讨论】:

    • 谢谢拉迪斯拉夫。如果您的名字出现在答案中,总会有很好的希望:-) - 对于命名关系:我也会远离那些。我的 OOP 思维告诉我要避免循环引用,因此我试图在附件中根本没有任何 FK,而是使用联结表。但这可能被过度设计了。
    • ... 是的,实际上业务逻辑已经被代码覆盖了。用户添加附件的唯一方法将始终符合业务规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多