直接从父实体删除实体时,不同的行为
我正在使用EF核心,我想跟踪实体的删除。现在,当当时使用ChangEtracking删除任何实体时,我会记录该实体,也需要记录IT父实体。
在这种情况下,我以简单的例子为例。在这家公司和部门中,有一对一的关系。
using Microsoft.EntityFrameworkCore;
public class SimpleDbContext
: DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Department> Departments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>().HasMany(cc => cc.Departments).WithOne(cc => cc.Company);
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=sampletracking;Integrated Security=SSPI");
base.OnConfiguring(optionsBuilder);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
foreach(var item in this.ChangeTracker.Entries())
{
if(item.State == EntityState.Deleted)
{
foreach(var itemRef in item.References)
{
if (!itemRef.IsLoaded)
itemRef.Load();
}
}
}
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
}
恩典
public class Company
{
public int Id { get; set; }
public string CompanyName { get; set; }
public List<Department> Departments { get; set; }
}
public class Department
{
public int Id { get; set; }
public string DepartmentName { get; set; }
public Company Company { get; set; }
}
准备记录。
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
Company company = new Company();
company.CompanyName = "Company-1";
company.Departments = new List<Department>();
company.Departments.Add(new Department() { DepartmentName = "Department-1" });
company.Departments.Add(new Department() { DepartmentName = "Department-2" });
simpleDbContext.Add(company);
await simpleDbContext.SaveChangesAsync();
}
方案1:删除儿童实体直接。
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
var department = simpleDbContext.Departments.Where(cc => cc.Id == 1).FirstOrDefault();
simpleDbContext.Remove(department);
await simpleDbContext.SaveChangesAsync();
}
在这种情况下,当SaveChange调用时,更改跟踪器检测删除及其加载引用(SO parent实体)时,然后成功加载。
方案2:
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
var company = simpleDbContext.Companies
.Include(cc => cc.Departments)
.Where(cc => cc.Id == 1).FirstOrDefault();
company.Departments.RemoveAll(cc => cc.Id == 2);
await simpleDbContext.SaveChangesAsync();
}
正在检测到此方案实体删除中删除的情况下,但是当它尝试加载参考时,它始终是null。
为什么如果相同的实体从同一集合中删除它的行为不同?
I am using EF core and I want to track deletion of entity. Now when any entity get deleted at that time using ChangeTracking I record that entity and also it is required to record it parent entity.
In this scenario I have took simple example. In this Company and Department has one to many relation.
using Microsoft.EntityFrameworkCore;
public class SimpleDbContext
: DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Department> Departments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>().HasMany(cc => cc.Departments).WithOne(cc => cc.Company);
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=sampletracking;Integrated Security=SSPI");
base.OnConfiguring(optionsBuilder);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
foreach(var item in this.ChangeTracker.Entries())
{
if(item.State == EntityState.Deleted)
{
foreach(var itemRef in item.References)
{
if (!itemRef.IsLoaded)
itemRef.Load();
}
}
}
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
}
Entties
public class Company
{
public int Id { get; set; }
public string CompanyName { get; set; }
public List<Department> Departments { get; set; }
}
public class Department
{
public int Id { get; set; }
public string DepartmentName { get; set; }
public Company Company { get; set; }
}
Prepare record.
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
Company company = new Company();
company.CompanyName = "Company-1";
company.Departments = new List<Department>();
company.Departments.Add(new Department() { DepartmentName = "Department-1" });
company.Departments.Add(new Department() { DepartmentName = "Department-2" });
simpleDbContext.Add(company);
await simpleDbContext.SaveChangesAsync();
}
Scenario 1 : Delete Child entity direct.
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
var department = simpleDbContext.Departments.Where(cc => cc.Id == 1).FirstOrDefault();
simpleDbContext.Remove(department);
await simpleDbContext.SaveChangesAsync();
}
In this scenario when savechange called, Change tracker detect the delete and when It load references ( so parent entity) then it successfully load.
Scenario 2: Delete from Parent
using (SimpleDbContext simpleDbContext = new SimpleDbContext())
{
var company = simpleDbContext.Companies
.Include(cc => cc.Departments)
.Where(cc => cc.Id == 1).FirstOrDefault();
company.Departments.RemoveAll(cc => cc.Id == 2);
await simpleDbContext.SaveChangesAsync();
}
In this scenario entity delete is being detected but when it try to load reference, it is always null.
Why if same entity delete from same collection it behave differently ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论