一列用于 Entity Framework Core 中两个不同表的外键
Posted
技术标签:
【中文标题】一列用于 Entity Framework Core 中两个不同表的外键【英文标题】:One column used to foreign key to two different tables in Entity Framework Core 【发布时间】:2021-11-26 01:41:00 【问题描述】:我有一些看起来像这样的实体:
public class Order
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderId get; set;
public string Description get; set;
public List<OrderDetail> OrderDetails get; set;
public class RoutedOrder
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int OrderId get; set;
public int RoutingNumber get; set;
public List<OrderDetail> OrderDetails get; set;
public class OrderDetail
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderDetailId get; set;
[ForeignKey("Order,RoutedOrder")]
public int OrderId get; set;
public Order Order get; set;
public RoutedOrder RoutedOrder get; set;
RoutedOrder
表是Order
表的“扩展”。并非Order
表中的所有行都最终在RoutedOrder
表中,但那些确实通过额外列获得了一些额外数据的行。但OrderId
列在两个表中的相关行的值相同。
因此,我不希望OrderDetail
中的两列指向每个实体。 (他们都使用OrderId
。)
当我构建模型时,OrderDetail
会添加一个名为 RoutedOrderOrderId
的属性。这会导致我的数据库保存失败(因为没有这样的列)。
如何让 Entity Framework Core 使用 OrderId
作为两个关系的外键?
更新:
我希望能够查询Orders
并获得对应的OrderDetails
列表(在OrderDetail
表中有该订单的OrderId
)。
我也希望能够对RoutedOrder
表执行相同的操作。 (查询RoutedOrders
并获取对应的OrderDetails
列表(在OrderDetail
表中有该RoutedOrder 的OrderId
。)
此外,虽然OrderId
在Order
和RoutedOrder
中存在相同的值,但我目前在它们之间没有任何外键。 (我直接查找它们,而不是通过链接)。虽然如果我需要在那里添加 FK 关系来完成这项工作,我可以做到。
【问题讨论】:
Order 和 RoutedOrder 之间似乎存在 1 对 0 或 1 的关系。为什么是 OrderDetail 表?如果我理解,您创建一个订单记录,您可能会也可能不会创建一个 RoutedOrder 记录。如果以及在创建 RoutedOrder 记录时,只需将 Order 表中的 OrderId 值用作 RoutedOrder 表中的 OrderId 值即可。 @GHDevOps - 你说得对,那里存在 1 到(0 或 1)的关系。 OrderDetail 表包含从 Order/RoutedOrder 到 OrderDetail 的一对多关系的子记录。我希望这些记录在 Order 实体和 RoutedOrder 实体上都可用。有时我在查询 RoutedOrder 时没有获得其完整的 Order 记录(实际上它非常大)。所以 Order 有很多 OrderDetails。而且由于 RoutedOrder 具有相同的主键(OrderId),它也有许多 OrderDetails。 @Vaccano 您希望OrderDetail
中的OrderId
列成为Order
和RoutedDetail
表的外键?这意味着当您有相应的Order
和RoutedOrder
行时,您只能拥有OrderDetail
行。这也意味着单个Order
行不能有任何OrderDetail
行(因为缺少RoutedOrder
中的外键)。这就是你想要的吗?
@Progman - 不完全是。我希望能够查询Orders
并获得相应的OrderDetails
列表(在OrderDetail
表中有该订单的OrderId
)。我也希望能够对RoutedOrder
表做同样的事情。 (查询RoutedOrders
并获取对应OrderDetails
的列表(在OrderDetail
表中有该RoutedOrder 的OrderId
。)
所以Order
和RoutedOrder
形成一个表-per-type heirachy? docs.microsoft.com/en-us/ef/core/modeling/…
【参考方案1】:
经过更多的尝试和错误,但我明白了:
public class Order
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderId get; set;
public string Description get; set;
public List<OrderDetail> OrderDetails get; set;
public class RoutedOrder
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int OrderId get; set;
public int RoutingNumber get; set;
[InverseProperty("RoutedOrder ")]
public List<OrderDetail> OrderDetails get; set;
public class OrderDetail
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderDetailId get; set;
public int OrderId get; set;
[ForeignKey("OrderId")]
public Order Order get; set;
[ForeignKey("OrderId")]
public RoutedOrder RoutedOrder get; set;
变化是:
在 RoutedOrder 中添加一个InverseProperty
属性,以便它知道要将其附加到哪个属性。
将ForeignKey
属性更改为导航属性并指向用于外键的字段/列。
这两个变化让它工作正常。
【讨论】:
以上是关于一列用于 Entity Framework Core 中两个不同表的外键的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 是不是可用于 Visual Studio 2008 Express Edition?
使用 Entity Framework 6.1 fluent API 创建唯一索引
用于简单数据模型和多对多关系的 Optimal Entity Framework 4 查询