能否在Entity Framework Core上下文外部为表设置全局筛选器?
解决EF Core软删除筛选器避免遗漏的方案
方法一:通过接口统一配置全局筛选器
先定义一个软删除接口,让所有需要软删除逻辑的实体实现它:
public interface ISoftDelete { bool Deleted { get; set; } } // 让你的Books实体实现该接口 public class Books : ISoftDelete { // 其他业务属性... public bool Deleted { get; set; } }
接着在DbContext的OnModelCreating方法中,批量为所有实现ISoftDelete的实体添加筛选器:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 遍历所有实体类型,自动给软删除实体加筛选器 foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) { // 动态构建筛选表达式 var parameter = Expression.Parameter(entityType.ClrType, "e"); var deletedProperty = Expression.Property(parameter, nameof(ISoftDelete.Deleted)); var notDeletedExpr = Expression.Not(deletedProperty); var filterLambda = Expression.Lambda(notDeletedExpr, parameter); modelBuilder.Entity(entityType.ClrType).HasQueryFilter(filterLambda); } } // 其他实体的单独配置... }
不管后续新增实体还是重建上下文,只要实体实现ISoftDelete接口,就会自动带上软删除筛选器,无需逐个配置。
方法二:封装基类DbContext固化筛选逻辑
如果担心重建上下文时忘记写批量配置代码,可以把筛选逻辑封装到基类DbContext中,后续所有业务上下文直接继承这个基类:
public class BaseSoftDeleteDbContext : DbContext { public BaseSoftDeleteDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 批量添加软删除筛选器的逻辑 foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) { var parameter = Expression.Parameter(entityType.ClrType, "e"); var deletedProperty = Expression.Property(parameter, nameof(ISoftDelete.Deleted)); var notDeletedExpr = Expression.Not(deletedProperty); var filterLambda = Expression.Lambda(notDeletedExpr, parameter); modelBuilder.Entity(entityType.ClrType).HasQueryFilter(filterLambda); } } } } // 你的业务上下文继承基类即可 public class YourDbContext : BaseSoftDeleteDbContext { public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) { } public DbSet<Books> Books { get; set; } // 其他DbSet和业务配置... }
后续重建上下文时,只要继承这个基类,软删除筛选器就会自动生效,完全不用担心遗漏。
方法三:外部扩展方法配置(可选)
如果需要从上下文外部抽离筛选逻辑,可以写一个扩展方法,在OnModelCreating中调用:
public static class SoftDeleteFilterExtensions { public static void ApplySoftDeleteFilters(this ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) { var parameter = Expression.Parameter(entityType.ClrType, "e"); var deletedProperty = Expression.Property(parameter, nameof(ISoftDelete.Deleted)); var notDeletedExpr = Expression.Not(deletedProperty); var filterLambda = Expression.Lambda(notDeletedExpr, parameter); modelBuilder.Entity(entityType.ClrType).HasQueryFilter(filterLambda); } } } }
然后在上下文的OnModelCreating里调用:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplySoftDeleteFilters(); // 其他配置... }
这种方式把筛选逻辑抽离到外部方法,即使重建上下文,只要记得调用这个扩展方法即可,比逐个配置实体筛选器更不容易出错。
内容的提问来源于stack exchange,提问作者user2227904
相关产品推荐
相关产品推荐

