【发布时间】:2018-02-06 11:19:48
【问题描述】:
我有一个使用实体框架将发票插入数据库表的解决方案。这些发票引用了一个订单,而订单又引用了一个订单项目集合。
在这种情况下,我试图将订单添加到数据库中,但是代码位于新的 DbContext 中,因此我需要将订单和订单项附加到上下文中,因为它们已经存在于数据库中并且不应该不会重新添加。
为了演示,我已经删减了模型属性:
public class Invoice {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int InvoiceId { get; set; }
public string OrderNumber { get; set; }
...
public virtual List<InvoiceLineItem> LineItems { get; set; }
}
public class InvoiceLineItem {
[Key]
public int Id { get; set; }
...
public ShopifyOrderItem { get; set; }
}
public class ShopifyOrder {
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
public int OrderNumber { get; set; }
...
public OrderInvoiceStatus InvoiceStatus { get; set; }
public virtual List<ShopifyOrderItem> OrderItems { get; set; }
}
public class ShopifyOrderItem {
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
...
[Required]
public virtual ShopifyOrder ShopifyOrder { get; set; }
}
在发票引擎中,我为每张发票运行以下代码以将其添加到数据库中:
ShopifyOrder order = await db.ShopifyOrders.SingleOrDefaultAsync(x => x.OrderNumber.ToString() == inv.OrderNumber);
if (order != null) {
// Attach marketplace entity to the invoice to avoid duplicate primary key exceptions
db.Marketplaces.Attach(inv.Marketplace);
db.Invoices.Add(inv);
order.InvoiceStatus = OrderInvoiceStatus.InProgress;
}
我尝试了多种方法来尝试附加状态,但是它们都抛出错误。
inv.LineItems.ForEach(li => {
db.Entry(li).State = EntityState.Unchanged;
db.Entry(li.ShopifyOrderItem).State = EntityState.Unchanged;
db.Entry(li.ShopifyOrderItem.ShopifyOrder).State = EntityState.Modified;
});
以上代码保存时返回如下错误:
EntityFramework:保存或接受更改失败,因为“TorroModels.ShopifyOrder”类型的多个实体具有相同的主键值。确保显式设置的主键值是唯一的。确保在数据库和实体框架模型中正确配置了数据库生成的主键。
在不尝试多次附加 ShopifyOrder 连接属性的情况下附加 LineItems/ShopifyOrderItems 的最佳方法是什么?
【问题讨论】:
标签: c# sql entity-framework