3

希望你能帮忙

我有 3 张(还有更多)桌子[Customer] [Order][Invoice].

所有这些表都有一个 ID 列[ID - Guid]

我有一张桌子[Notes],它由两列组成(为简洁起见):-

[ID - Guid]
[ParentFKID - Guid]
[Comment - String]

我希望[Notes]在 3 个(以及更多)“父”实体中的每一个上创建一个集合,并配置每个实体以填充表中的集合,[Notes]其中相关父表的主键指向该[ParentFKID]列.

所以本质上该列[ParentFKID]是一个外键,但是是多个其他表的外键。这是可能的,因为我们使用的是 GUID 键。

这本质上是因为我们没有复制 and 的表,[CustomerNotes] [OrderNotes]并且[InvoiceNotes]还避免了另一种选择,即让 notes 表永远随着外键[Customer_ID] [Order_ID]和增长而增长[Invoice_ID]

当然,必须有一种方法可以通过 Fluent API 映射来解决这个问题,但由于我对 EF Code First 和 Fluent API 还很陌生,所以我很难看到它。

我不在乎约束可能不可用-无论如何这都是可取的,而且结构似乎不可能。这肯定是一种常见的情况。

任何人都可以提供帮助并提供一个示例,说明如何为模型配置实体以启用此场景吗?

4

1 回答 1

2

您可以使用 Fluent API 尝试此映射:

modelBuilder.Entity<Customer>()
    .HasMany(c => c.Notes)
    .WithRequired()
    .HasForeignKey(n => n.ParentFKID);

modelBuilder.Entity<Order>()
    .HasMany(o => o.Notes)
    .WithRequired()
    .HasForeignKey(n => n.ParentFKID);

modelBuilder.Entity<Invoice>()
    .HasMany(i => i.Notes)
    .WithRequired()
    .HasForeignKey(n => n.ParentFKID);

我希望这ParentFKID是您班级中 FK的属性。如果您不希望替换为:NoteHasForeignKey.Map(m => m.MapKey("ParentFKID"));


编辑

对共享 FK 列使用独立关联(即MapKey在类中不使用 FK 属性Note)不起作用并在定义映射时引发异常。


请记住,如果您要使用 Code-First创建数据库模式,EF 将强制执行所有 FK 约束。然后您必须在数据库中手动禁用它(或者也许也可以使用基于代码的自定义迁移,但我不知道是否以及如何)。

我还期望该ParentFKID列不可为空(因此WithRequired),因为我想,没有父级的注释没有意义。

我建议避免在Note类中使用父级(客户、订单和发票)的导航属性。如果您尝试加载包含其父级的注释 - 并且您必须包含所有三个可能的父级导航属性,因为您无法从给定注释中知道父级具有哪种类型 - EF 将创建INNER JOIN查询(由于所需的关系和因为它期望强制执行约束)并且这将不返回任何结果,甚至不返回父级。(尽管 FK 不允许使用值,但您可以INNER JOIN使用WithOptional而不是来破解。EF 会在急切加载父母时创建一个then 。)WithRequiredNULLLEFT OUTER JOIN

我真的不确定这一切是否会奏​​效并且不会产生意外的副作用。尽管您说这是一种常见情况,但 EF 没有明确支持没有强制约束的关系。

EF 将更好地支持的一个场景是拥有一个EntityWithNotes承载Notes集合的基础实体,以及从哪个CustomerOrder派生Invoice的。EntityWithNotes您将只定义和之间的单一关系Note。在数据库方面,您可以选择将Customer,OrderInvoice放入单个表(按层次结构表(TPH)映射),考虑到这些实体的业务含义有多么不同,这听起来确实很荒谬。我什至不会考虑。或者,您将、Customer放入不同的表中(Table-Per-Type (TPT) 映射)。但是,TPT 并不是真正以最佳性能而闻名。对于如此重要​​的实体和可能快速增长的表格,我不会真正考虑这一点。OrderInvoice EntityWithNotes

编辑

虽然与开头所示的共享 FK 属性的映射有效,但当我删除数据库中外键约束的强制执行时,我得到了其他异常。尽管我可以成功保存数据,但我得到了关于不一致状态的异常,ObjectContext因为显然上下文总是期望强制执行约束。

我建议远离这个模型,并为CustomerNotes,OrderNotes和使用单独的表格InvoiceNotes。如果这是不可能的(现有且不可更改的数据库模式?)实体框架是否是此类模式的合适工具是值得怀疑的。

于 2013-09-27T21:25:33.540 回答