gpt4 book ai didi

c# - EF Code First 多个父项的单个外键

转载 作者:行者123 更新时间:2023-11-30 17:03:02 25 4
gpt4 key购买 nike

希望能帮到你

我有 3 个(还有更多)表 [Customer] [Order][Invoice]

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

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

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

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

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

这本质上是为了让我们没有 [CustomerNotes] [OrderNotes][InvoiceNotes] 的复制表,同时也避免了使用其他备选方案表永远随着外键 [Customer_ID] [Order_ID][Invoice_ID]

增长

肯定有一种方法可以通过 Fluent API 映射来满足这一要求,但由于我对 EF Code First 和 Fluent API 还很陌生,所以我很难看到它。

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

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

最佳答案

您可以使用 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 是您的 Note 类中 FK 的属性 如果您不希望将 HasForeignKey 替换为: .Map(m => m.MapKey("ParentFKID"));


编辑

在共享 FK 列中使用独立关联(即在 Note 类中使用没有 FK 属性的 MapKey)不起作用,并且在定义映射时会抛出异常。


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

我还预计 ParentFKID 列不可为空(因此 WithRequired),因为我猜,没有父项的注释没有意义。

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

我真的不确定是否所有这些都有效并且没有不良副作用。尽管您说这是一种常见的情况,但 EF 没有明确支持没有强制约束的关系。

EF 可以更好地支持的场景是拥有一个基本实体 EntityWithNotes,它携带 Notes 集合以及 CustomerOrder Invoice 派生自。您将只定义 EntityWithNotesNote 之间的单一关系。在数据库方面,您可以选择将 CustomerOrderInvoice 放入单个表中(Table-Per-Hierarchy (TPH) 映射)考虑到这些实体的商业意义有多么不同,这听起来真的很荒谬。我什至不会去想它。或者你把 Customer, Order, Invoice EntityWithNotes 放到不同的表中(表- 每类型 (TPT) 映射)。但是,TPT 并不是真正以最佳性能而闻名。对于如此重要​​的实体和可能快速增长的表格,我真的不会考虑这一点。

编辑

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

我建议远离此模型并为 CustomerNotesOrderNotesInvoiceNotes 使用单独的表。如果那不可能(现有且不可更改的数据库架构?), Entity Framework 是否适合此类架构的工具就值得怀疑。

关于c# - EF Code First 多个父项的单个外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19052860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com