3

我已经阅读了实体框架一对一映射问题,这不是重复的,因为这里的业务规则规范不同。

有两个表,发票和订单。

Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Primary, Auto Number)
-> InvoiceID (FK InvoiceID of Invoices Table)

现在的问题是,如果属性名称不同,EF 需要此关联的一对多关系。如果属性名称相同,则它服务于派生类的目的,但这里的订单不是派生类或发票。

为每个购物车生成 InvoiceID(s),但 OrderID(s) 仅针对已支付的发票生成,因此每个 Order 都有 InvoiceID,但每个 Order 没有对应的 Invoice。

如果我为此创建一个单独的表,那么我必须编写太多代码才能做到这一点。有什么办法可以消除这个限制,让 EF 仍然处理我的模型。

但是,目前如果我如下更改模型,它可以工作

Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Auto Number)
-> InvoiceID (Primary, FK InvoiceID of Invoices Table)

但这是好的做法吗?因为根据定义,Orders 表的 InvoiceID 肯定是唯一的,但我们将在任何地方引用 OrderID 以进行比较和许多其他引用。我知道我可以索引该属性,但我不觉得这个设计是完美的。

一对一错误

4

1 回答 1

2

这里似乎显而易见的解决方案是将 EDM 中 Invoice 和 Order 之间的 1:* 关联更改为 1:1 关联。但是,正如您所经历的,当您在模型中的两个实体之间 具有外键关联时,映射将不会验证。

映射唯一外键关联的唯一方法是使用 独立关联。这与我们在 EF3.5 中使用的关联类型相同,其中不支持外键。

将外键关联转换为独立关联意味着从 Order 实体中移除 InvoiceID 外键并通过映射重新创建关联。

要更改关联,您需要执行以下操作:

  1. 从 Order 实体中删除 InvoiceID 外键属性。
  2. 选择发票和订单之间的关联。
  3. 在关联的“属性”窗口中,通过单击该属性旁边的省略号打开引用约束。
  4. 单击“删除”按钮删除约束。
  5. 在 Designer 中右键单击关联,然后从上下文菜单中选择表映射。
  6. 在映射详细信息窗口中,单击元素以显示下拉菜单。
  7. 从下拉列表中,选择订单。映射应自动填充。
  8. 返回关联的“属性”窗口。
  9. 对于名为“End2 Multiplicity”的属性,其当前值为 * Collection of Orders,使用其下拉列表将该属性更改为 1(订单之一)。
  10. 通过右键单击设计图面并选择验证来验证模型。您将看到与此映射相关的错误消息消失了。

在您的应用程序中遇到此问题时,您必须决定哪个对您的模型和应用程序逻辑更重要:外键标量(例如,Order.InvoiceID)或能够定义一个实体之间的 1:1 关联(Invoice) 和另一个 (Order) 通过外键 (InvoiceID) 连接时。

好消息是新的 EF4.0延迟加载仍将与独立关联一起使用,只是外键没有暴露。为此,您必须转到导航属性 (Invoice) 并读取其 InvoiceID,如下面的代码:

Order order = context.Orders.First();
int invoiceID = order.Invoice.InvoiceID;

或者您可以使用下面的代码在 Order 实体上直接读取它,而无需延迟加载或急切加载 Invoice 属性:

int invoiceID = order.InvoiceReference.EntityKey.EntityKeyValues[0].Value;
于 2010-11-10T15:01:36.593 回答