我有一个使用Entity Framework将发票插入数据库表的解决方案。这些发票引用订单,而订单又引用订单商品集合。
在这个例子中,我试图向数据库添加一个订单,但是代码在新的DbContext中,所以我需要将订单和订单项附加到上下文,因为这些已经存在于数据库中并且不应该&# 39;重新加入。
为了演示,我已经删除了模型属性:
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:保存或接受更改失败,因为多个类型的实体&#39; TorroModels.ShopifyOrder&#39;具有相同的主键值。确保显式设置的主键值是唯一的。确保在数据库和Entity Framework模型中正确配置了数据库生成的主键。
在不尝试多次附加ShopifyOrder连接属性的情况下附加LineItems / ShopifyOrderItems的最佳方法是什么?
答案 0 :(得分:0)
很抱歉,但在构建关系时,您似乎需要先遵循最佳做法。您可以点这个链接:
http://www.entityframeworktutorial.net/entity-relationships.aspx
简而言之:
接下来,您可以阅读以下链接:
http://www.entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx
如果您需要了解更多关于附加实体的最佳做法,但在我看来,不要滥用此功能,因为在大多数情况下使用普通CRUD应该足够了。 / p>
对不起,我不能帮助你,因为我可能需要的信息不足,而且我的声誉仍然无法直接在你的帖子中发表评论。