我正在尝试在我们的 EF 6 项目中实现软删除。我们正在使用数据库优先方法,我注意到您无法覆盖
OnModelCreating
。
使用代码优先方法时,可以对特定实体应用全局过滤器,如本博客文章中所述。
如何使用数据库优先方法重新创建它?
public class MyContext : DbContext
{
public virtual IDbSet<Company> Companies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.Map(m => m.Requires("IsDeleted").HasValue(false))
.Ignore(m => m.IsDeleted);
}
}
public class MyContext : DbContext
{
public virtual IDbSet<Company> Companies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.Map(m => m.Requires("IsDeleted").HasValue(false))
.Ignore(m => m.IsDeleted);
base.OnModelCreating(modelBuilder);
}
}
需要编写base.OnModelCreating(modelBuilder);构建您的查询,我还在帖子中突出显示了这一行。
在执行操作之前需要以这种形式定义一个构造函数:
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
public virtual DbSet<Company> Companies { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.Map(m => m.Requires("IsDeleted").HasValue(false))
.Ignore(m => m.IsDeleted);
base.OnModelCreating(modelBuilder);
}
如果您使用数据库优先方法,则不需要为 IsDeleted 标志添加 OnModelCreating。当您编写自定义 SaveChanges 方法时,您可以处理。不要忘记 ChangeTracker 必须打开。
例如;
public int SaveChanges(){
var changeSet = ChangeTracker.Entries();
foreach (var entry in changeSet.Where(c => c.State == System.Data.Entity.EntityState.Added)){
var info = entry.Entity.GetType()
.GetProperty("IsDeleted", BindingFlags.Public | BindingFlags.Instance);
if ( info!=null && info.CanWrite){
info.SetValue(entry.Entity, false, null);
}
}
base.SaveChanges();
}
标准化软删除实体的最佳方法,下面将逐步解释。
1- 创建ISoftDelete接口:
public interface ISoftDelete
{
bool IsDeleted { get; set; }
}
2- 然后创建您想要实施软删除方法的实体。
public class Company : ISoftDelete
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long CompanyId { get; set; }
public string Name { get; set; }
public bool IsDeleted { get; set; }
}
3- 通过重写 DBContext.SaveChanges() 方法将实体的状态从“已删除”更改为“已修改”,如下所示。
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries().Where(p => p.State == EntityState.Deleted))
TryCancelDeletion(entry);
return base.SaveChanges();
}
private bool TryCancelDeletion(EntityEntry entry)
{
if (!(entry.Entity is ISoftDelete))
return false;
entry.Reload();
entry.State = EntityState.Modified;
((ISoftDelete)entry.Entity).IsDeleted = true;
return true;
}
软删除实体并未真正删除,在数据库中标记为 IsDeleted = true,但无法正常检索到应用程序。
您应该应用默认过滤器从结果中排除软删除的实体。