EF核心无法跟踪子集合的更改

时间:2018-07-26 10:42:41

标签: c# entity-framework asp.net-core ef-core-2.1

我有这些型号

public class WarehouseAllocation
{
   public int Id { get; set; }
   public Warehouse Warehouse { get; set; }
   public IList<Dispatch> Dispatches { get; set; }
   //---- removed other properties for brevity
}

public class Dispatch 
{
   public int Id { get; set; }
   public IList<DispatchDetail> DispatchDetails { get; set; }
   //---- removed other properties for brevity
}

在数据库上

分派有一个外键 WarehouseAllocationId ,它引用WarehouseAllocation表。

我使用Fluent API将模型映射到数据库,如下所示:

modelBuilder.Entity<WarehouseAllocation>(m =>
{
    m.ToTable("WarehouseAllocation");

    m.Property(wa => wa.Id).HasColumnName("WarehouseAllocationId")
         .ValueGeneratedOnAdd();

    m.HasKey(wa => wa.Id);

    m.HasOne(wa => wa.Warehouse)
        .WithMany()
        .HasForeignKey("WarehouseId");

    m.HasMany(w => w.Dispatches)
        .WithOne();
});

modelBuilder.Entity<Dispatch>(m =>
{
    m.ToTable("Dispatch");

    m.Property(wa => wa.Id).HasColumnName("DispatchId")
         .ValueGeneratedOnAdd();

    m.HasKey(wa => wa.Id);
});

当我打电话时     dbContext.WarehouseAllocations .Include(w => w.Dispatches) .ThenInclude(w => w.DispatchDetails).ToList(), Ef core检索所有仓库分配及其调度,包括详细信息。

问题是当我使用此方法时:

var warehouseAllocation = dbContext.WarehouseAllocations
    .Include(w => w.Dispatches)
    .ThenInclude(d => d.DispatchDetails)
    .SingleOrDefault(w => w.Id == warehouseAllocationId);

warehouseAllocation.Dispatches.Add(new Dispatch
{
   //--including other properties
   DispatchDetails = new List<DispatchDetail> {
       new DispatchDetail
       {
          //--other properties
       }
   }
});

// call another query that includes WarehouseAllocation

dbContext.ChangeTracker.HasChanges() // this is false

dbContext.SaveChanges() // this keeps returning zero

为什么未检测到更改?

已更新

在进行更改之后,在调用SaveChanges()之前,出于业务事件的考虑,我调用了一个包含仓库分配的linq查询。 Ef核心会覆盖当前实体状态吗?

2 个答案:

答案 0 :(得分:0)

问题是,在调用SaveChanges()之前,我正在进行另一个查询,其中包括仓库分配。

var shipment = _myDbContext.Shipments
                .Include(s => s.WarehouseAllocations)
                .ThenInclude(s => s.Dispatches)
                .ThenInclude(s => s.DispatchDetails)
                .Include(s => s.WarehouseAllocations)
                .SingleOrDefault(s => s.WarehouseAllocations.Select(w => w.Id).Contains(warheouseAllocationId));

然后我在货件上执行一些业务事件逻辑,并保存所有更改。(现在我可以用更好的方式做到这一点)

我猜,如果在保存您的更改之前进行包含受影响的实体类型的查询,Ef会覆盖实体状态。

答案 1 :(得分:-1)

如果您更改:

 var warehouseAllocation = dbContext.WarehouseAllocations
 .Include(w => w.Dispatches)
 .SingleOrDefault(w => w.Id == warehouseAllocationId);

收件人:

 var warehouseAllocation = dbContext.WarehouseAllocations
 .Include(w => w.Dispatches)
 .ThenInclude(d => d.DispatchDetail)
 .SingleOrDefault(w => w.Id == warehouseAllocationId);

它应通知EF您希望将DispatchDetail包含在其变更跟踪器中。这还将从数据库中提取w的所有DispatchDetail值。