【问题标题】:Entity Framework Core, deleting items from nested collectionEntity Framework Core,从嵌套集合中删除项目
【发布时间】:2018-07-13 19:40:29
【问题描述】:

我有两门课

 public class InvoiceRow
    {
        public int Id { get; set; }
        public int InvoiceId { get; set; }

        public int ProductId { get; set; }
        public virtual Product Product { get; set; }

        public int Amount { get; set; }
    }



   public class Invoice
    {
            public int Id { get; set; }
            private ICollection<InvoiceRow> _rows;
            public virtual ICollection<InvoiceRow> Rows => _rows ?? (_rows = new List<InvoiceRow>());
    }

我在存储库类中使用 Update 方法

  public void Update(Invoice record)
  {
            dB.Invoices.Update(record);
            dB.SaveChanges();
  }

它适用于更新行集合中的值并添加新行,但是如果我传递的对象的行数少于数据库中的行数,它不会删除项目。最好的方法是什么?

【问题讨论】:

    标签: c# entity-framework entity-framework-core


    【解决方案1】:

    那是因为数据库中的行没有被标记为删除。

    仅更新新的或更改的项目。集合中的“缺失”项目不会被视为已删除。

    因此,您需要自己标记要删除的项目。像这样的:

    public void Update(Invoice record)
    {
        var missingRows = dB.InvoiceRows.Where(i => i.InvoiceId == record.Id)
                            .Except(record.Rows);
        dB.InvoiceRows.RemoveRange(missingRows);
    
        dB.Invoices.Update(record);
        dB.SaveChanges();
    }
    

    【讨论】:

    • 这会导致 InvalidOperationException:无法跟踪实体类型“发票”的实例,因为已经在跟踪具有相同键值 {'Id'} 的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看冲突的键值。
    • 我找到了异常的原因,我们得到了两个分别跟踪的实例。 var missingRows = dB.InvoiceRows.Where(i => i.InvoiceId == record.Id).Except(record.Rows); dB.InvoiceRows.RemoveRange(missingRows);这样就可以了
    • 我已经用您评论中的信息更新了答案。
    • Except 在这里不起作用,因为它比较对象引用,而不是值。也就是说,除非InvoiceRow 实现IEquatable,覆盖EqualsGetHashcode。或者您也可以将IEqualityComparer 传递给Except。或者您可以将.Except(record.Rows) 替换为.Where(ir =&gt; !record.Rows.Any(rr =&gt; rr.Id == ir.Id))
    【解决方案2】:

    另一种解决方案是声明一个复合主键InvoiceRow.Id InvoiceRow.InvoiceId。现在它是一个识别关系。因此,当子记录从父记录中移除时,EF Core 确实会删除它们。

    https://stackoverflow.com/a/17726414/7718171

    https://stackoverflow.com/a/762994/7718171

    remove-from-collection-does-not-mark-object-as-deleted

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 2017-02-11
      相关资源
      最近更新 更多