【问题标题】:Duplicate entities when setting state within a collection in Entity Framework在实体框架中的集合中设置状态时重复实体
【发布时间】: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


    【解决方案1】:

    很抱歉,但在建立关系时,您似乎需要先遵循最佳实践。你可以点击这个链接:

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

    简而言之:

    1. 避免在每个实体中仅使用“Id”,或者您可以使用属性在物理名称和属性名称之间进行映射
    2. 你这里好像有循环引用,或许你可以先简化一下

    接下来,你可以阅读这个链接:

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

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

    很抱歉,由于缺乏我可能需要的信息,我无法为您提供更多帮助,而且以我的声誉,我仍然无法直接在您的帖子中发表评论以寻求帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      相关资源
      最近更新 更多