您可以使用 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的属性。如果您不希望替换为:Note
HasForeignKey
.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 。)WithRequired
NULL
LEFT OUTER JOIN
我真的不确定这一切是否会奏效并且不会产生意外的副作用。尽管您说这是一种常见情况,但 EF 没有明确支持没有强制约束的关系。
EF 将更好地支持的一个场景是拥有一个EntityWithNotes
承载Notes
集合的基础实体,以及从哪个Customer
和Order
派生Invoice
的。EntityWithNotes
您将只定义和之间的单一关系Note
。在数据库方面,您可以选择将Customer
,Order
和Invoice
放入单个表(按层次结构表(TPH)映射),考虑到这些实体的业务含义有多么不同,这听起来确实很荒谬。我什至不会考虑。或者,您将、Customer
和放入不同的表中(Table-Per-Type (TPT) 映射)。但是,TPT 并不是真正以最佳性能而闻名。对于如此重要的实体和可能快速增长的表格,我不会真正考虑这一点。Order
Invoice
EntityWithNotes
编辑
虽然与开头所示的共享 FK 属性的映射有效,但当我删除数据库中外键约束的强制执行时,我得到了其他异常。尽管我可以成功保存数据,但我得到了关于不一致状态的异常,ObjectContext
因为显然上下文总是期望强制执行约束。
我建议远离这个模型,并为CustomerNotes
,OrderNotes
和使用单独的表格InvoiceNotes
。如果这是不可能的(现有且不可更改的数据库模式?)实体框架是否是此类模式的合适工具是值得怀疑的。