Entity Framework Core,从嵌套集合中删除项目

问题描述 投票:0回答:4

我有两节课

 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
4个回答
21
投票

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

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

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

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();
}

3
投票

我正在使用 Entity Framework Core 6,以下代码适用于我。

public void Update(Invoice invoice)
{

        //1. valid invoice rows ids
        var validInvoiceRowIds = invoice.InvoiceRows.Select(ir => ir.Id).ToList();

        //2. missing invoice rows
        var missItems = _context.InvoiceRows
            .Where(ir => ir.InvoiceId == invoice.Id && !validInvoiceRowIds.Contains(ir.Id))
            .ToList();

        _context.RemoveRange(missItems);

        _context.Update(entity);
        _context.SaveChanges();

}

1
投票

另一种解决方案是声明一个复合主键

InvoiceRow.Id
InvoiceRow.InvoiceId
。现在它是一个识别关系。因此,当子记录从父记录中删除时,EF Core 确实会删除子记录。

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

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

从集合中删除不将对象标记为已删除


0
投票

另一个解决方案是在调用 SaveChanges() 之前将已删除的 InvoiceRows EntityState 更改为已删除

DbContext.Entry(invoiceRow).State = EntityState.Deleted;

 DbContext.Set<T>().Entry(entity).State = EntityState.Deleted;

然后 SaveChanges() 将删除删除的行。

© www.soinside.com 2019 - 2024. All rights reserved.