我正在尝试让标识关系在实体框架中工作,以便我可以使用 Remove 从其集合中删除项目。
我创建了一个测试,例如:
public class OrderLine{
[Key, Column(Order = 0)]
public int OrderLineId { get; set; }
[Key, ForeignKey("Order"), Column(Order = 1)]
public int OrderId{ get; set; }
public virtual Order Order{ get; set; }
[ForeignKey("Product")]
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int Number { get; set; }}
当我尝试添加订单行时,例如:
var order=_orderRepository.Find(1);
var NewOrderLine= new OrderLine()
{
Number = 1,ProductId= 2
};
order.OrderLines.Add(NewOrderLine);
_orderRepository.InsertOrUpdate(order);
_orderRepository.Save();
我收到错误
无法在表中插入标识列的显式值 "订单行"(当IDENTITY_INSERT设置为 OFF 时。
当我查看表时,SQL在OrderId和OrderLineId上有一个主键。此外,只有 OrderLineId 被设置为标识。所以它一定是试图插入一个值,但它似乎试图插入的唯一值是 0。
我可以使用以下方法插入表格的任何想法:
INSERT INTO [OrderLines]
([ProductId ]
,[Number]
,[OrderId])
VALUES
(2
,1
,1)
异常意味着表 OrderLines
中的复合主键列之一是数据库中自动生成的标识(我猜该列OrderLineId
),但 EF 确实将一个值(0
,因为您在 INSERT 语句中为此列创建新OrderLine
时未指定属性)到数据库,因为该属性未在 EF 模型中标记为标识。默认情况下(= IDENTITY_INSERT
OFF
),SQL Server 不允许将值显式插入标识列。
实际上,在您的映射中,键列不是标识,因为默认情况下,在组合键中没有属性是标识。
我认为,解决方案是关闭数据库中的身份规范,或者在模型中将属性标记为身份:
public class OrderLine
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderLineId { get; set; }
[Key, ForeignKey("Order"), Column(Order = 1)]
public int OrderId { get; set; }
public virtual Order Order { get; set; }
// ...
}
DatabaseGeneratedOption.Identity
意味着 EF 期望在数据库中生成列值,因此当您尝试插入新实体时,不会将该值发送到数据库。