【问题标题】:One column used to foreign key to two different tables in Entity Framework Core一列用于 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。)

此外,虽然OrderIdOrderRoutedOrder 中存在相同的值,但我目前在它们之间没有任何外键。 (我直接查找它们,而不是通过链接)。虽然如果我需要在那里添加 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 列成为OrderRoutedDetail 表的外键?这意味着当您有相应的OrderRoutedOrder 行时,您只能拥有OrderDetail 行。这也意味着单个Order 行不能有任何OrderDetail 行(因为缺少RoutedOrder 中的外键)。这就是你想要的吗?
  • @Progman - 不完全是。我希望能够查询Orders 并获得相应的OrderDetails 列表(在OrderDetail 表中有该订单的OrderId)。我也希望能够对RoutedOrder 表做同样的事情。 (查询RoutedOrders 并获取对应OrderDetails 的列表(在OrderDetail 表中有该RoutedOrder 的OrderId。)
  • 所以OrderRoutedOrder 形成一个表-per-type heirachy? docs.microsoft.com/en-us/ef/core/modeling/…

标签: c# entity-framework-core asp.net-core-3.1 .net-core-3.1


【解决方案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 属性更改为导航属性并指向用于外键的字段/列。

这两个变化让它工作正常。

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2019-10-15
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多