在Entity Framework中的集合中设置状态时重复实体

时间:2018-02-05 11:53:08

标签: c# sql entity-framework

我有一个使用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的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

很抱歉,但在构建关系时,您似乎需要先遵循最佳做法。您可以点这个链接:

http://www.entityframeworktutorial.net/entity-relationships.aspx

简而言之:

  1. 避免仅使用&#34; Id&#34;在每个实体中,或者您可以使用属性在物理名称和属性名称之间进行映射
  2. 这里似乎有循环引用,所以也许你可以先简化它
  3. 接下来,您可以阅读以下链接:

    http://www.entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx

    如果您需要了解更多关于附加实体的最佳做法,但在我看来,不要滥用此功能,因为在大多数情况下使用普通CRUD应该足够了。 / p>

    对不起,我不能帮助你,因为我可能需要的信息不足,而且我的声誉仍然无法直接在你的帖子中发表评论。