【问题标题】:EF Code-First Foreign Key Creating Duplicate DataEF 代码优先外键创建重复数据
【发布时间】:2011-12-12 03:37:00
【问题描述】:

我在使用 Code-First ForeignKey 时遇到了一些问题。我有一个如下所述的产品,我正在尝试使用该现有产品创建一个新的 LineItem。但是,当我将更改保存到我的上下文时,它会创建一个全新的产品,但它是我最初使用的产品的副本,除了 id 是新的(现在数据库中的新记录)。

这是我要添加新订单项的地方:

public void AddItem(Product item) {
    // checking item.Id here will return 100
    var lineItem = new LineItem
                    {
                      CartId = this.Id,
                      Product = item,
                      ProductId = item.Id,
                      Quantity = 1
                    };

    _db.LineItems.Add(lineItem);
    _db.SaveChanges();

    // checking lineItem.Id here returns 101
    // also checking item.Id here now also returns 101

    this.LineItems.Add(lineItem);
}


public class LineItem {
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    public int CartId { get; set; }

    [Required]
    public int ProductId { get; set; }

    [Required]
    public int Quantity { get; set; }

    [ForeignKey("CartId")]
    public virtual Cart Cart { get; set; }

    [ForeignKey("ProductId")]
    public virtual Product Product { get; set; }
}

为什么要创建新产品?

【问题讨论】:

  • 加载你传入的产品的代码在哪里?我希望这个产品实例不再附加到上下文中,因此被视为新记录。作为测试,在您的新 LineItem 上保留 Product = null 并设置 ProductId。
  • 啊,是的,这就是问题所在。我正在缓存我的产品集合并使用该缓存集合中的产品。如果您回答,我会将您标记为答案。附带说明一下,有什么方法可以使用我的缓存版本的产品吗?

标签: c# foreign-keys ef-code-first


【解决方案1】:

解决您的问题的另一种方法是将与您添加 Products 的上下文相同的上下文传递给 AddItem 方法。 这样您就可以确保用于 LineItems 的上下文不会被分离,并且 EF 不会看到需要再次添加 Products(或任何其他实体)。

最好的问候,

阿迪·康斯坦丁

【讨论】:

    【解决方案2】:

    根据 cmets,您使用的是产品对象的未附加副本。因此,EF 在附加时将其视为一个新实例(通过LineItem.Product setter 中生成的代码并相应地插入它。

    你可以像这样重新附加你的实体

    _db.Products.Attach(product);
    

    【讨论】:

      猜你喜欢
      • 2018-02-13
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 2014-03-28
      相关资源
      最近更新 更多