当我有这样的模型时...
public class Order
{
[Key, Column(Order = 1)]
public int CustomerId { get; set; }
[Key, Column(Order = 2)]
public int OrderId { get; set; }
public ICollection<OrderItem> Items { get; set; }
}
public class OrderItem
{
[Key, Column(Order = 1)]
public int CustomerId { get; set; }
[Key, Column(Order = 2)]
public int OrderId { get; set; }
[Key, Column(Order = 3)]
public int OrderItemId { get; set; }
}
...当我将图形添加到数据库时OrderItem.CustomerId
,我不需要手动提供外键值:OrderItem.OrderId
Order - OrderItems
var order = new Order
{
CustomerId = 5,
OrderId = 1,
Items = new List<OrderItem>
{
// I don't need to set CustomerId and OrderId here
new OrderItem { OrderItemId = 12 }
}
};
context.Orders.Add(order);
context.SaveChanges();
SaveChanges
将生成 SQL 语句来插入Order
和OrderItem
. 因为OrderItem
它是:
exec sp_executesql N'insert
[dbo].[OrderItems]([CustomerId], [OrderId], [OrderItemId])
values (@0, @1, @2)
',N'@0 int,@1 int,@2 int',@0=5,@1=1,@2=12
因此,FKCustomerId
和OrderId
正确设置(@0=5
和@1=1
)。
Customer
但是,如果我通过将导航属性添加到模型来向模型添加与实体的另一个关系Order
...
public Customer Customer { get; set; }
......Customer
像这样的课程......
public class Customer
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CustomerId { get; set; }
}
...并调用与上面相同的代码(假设数据库中存在Customer
with CustomerId
= 5
)我得到以下 SQL:
exec sp_executesql N'insert
[dbo].[OrderItems]([CustomerId], [OrderId], [OrderItemId])
values (@0, @1, @2)
',N'@0 int,@1 int,@2 int',@0=0,@1=1,@2=12
几乎相同,但CustomerId
在0
这种情况下 ( @0=0
) 会导致关系违反外键约束Order - OrderItem
。如果存在Customer
with CustomerId
=0
并且该客户有Order
with OrderId
= 1
,则不会发生异常,并且OrderItem
将被添加到可能比异常更糟糕的错误订单中。
可以通过在 new 中设置CustomerId
(它是 FK 的一部分)来解决该问题OrderItem
:
Items = new List<OrderItem>
{
// I don't need to set OrderId here, BUT CustomerId
new OrderItem { CustomerId = 5, OrderItemId = 12 }
}
或者 - 可以通过将带有 Id 的客户附加5
到上下文来修复它(我不知道它为什么会起作用)。
是否有合理的解释为什么我必须手动提供 FK(或本示例中的 FK 的一部分)或者这是一个错误?
(我在这个模型中使用了 EF 5.0 和 .NET 4.0。)