Skip to main content
 首页 » 编程设计

c#之Ef 核心不跟踪子集合的更改

2024年01月13日36findumars

我有这些模型

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 
} 

在数据库上,

Dispatch 有一个外键 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 核心是否会覆盖当前实体状态?

请您参考如下方法:

问题是,我在调用 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)); 

然后我对 Shipment 执行一些业务事件逻辑并保存所有更改。 (现在我可以用更好的方式来做)

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