You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:12:53