C#怎么实现EF Core软删除 C#如何用EF Core全局过滤器实现数据软删除和逻辑删除【数据库】
EF Core软删除必须通过HasQueryFilter配置全局查询过滤器并配合拦截SaveChanges实现逻辑删除。需为实体显式配置IsDeleted字段的过滤条件,重写删除行为为更新操作,必要时用IgnoreQueryFilters绕过过滤,并为IsDeleted字段建立索引以保障性能。EF Core 软删除必须靠 HasQueryFilter 配合字段标记软删除不是“删数据”,而是让查询自动过滤掉被标记为已删除的记录。EF Core 不提供开箱即用的“软删开关”,核心依赖 HasQueryFilter 在模型配置中注入全局 WHERE 条件。没配这个,哪怕数据库里加了 IsDeleted 字段,查询照样返回所有行。常见错误现象:context.Users.ToList() 仍查出已“删除”的用户;调用 Remove() 后数据真被物理删了;或者手动写 .Where(x => !x.IsDeleted) 到处都是,漏一处就出问题。必须在 OnModelCreating 中为每个需软删除的实体显式配置 HasQueryFilter,不能只靠约定推荐统一使用 bool IsDeleted 字段(而非 DateTime? DeletedAt),避免空值比较引发的 SQL NULL 语义陷阱如果实体有继承关系(如 AuditEntity 基类),HasQueryFilter 可以写在基类映射里,但子类若重写该属性,需确保类型转换安全删除操作要重写 SaveChanges 或用拦截器,不能直接 Remove()EF Core 默认的 Remove() 是物理删除。想实现“点删除变更新”,得拦截保存动作,把 EntityState.Deleted 实体转成 EntityState.Modified 并设置 IsDeleted = true。否则,哪怕配了 HasQueryFilter,数据也早被 DELETE 语句干掉了。使用场景:管理后台点击“删除用户”,后端 API 接收请求后调用 context.Users.Remove(user) —— 这行代码本身不危险,危险的是紧接着的 SaveChanges()。推荐用 SaveChangesInterceptor(EF Core 5.0+),比重写 SaveChanges 更干净,避免递归调用风险拦截时只处理状态为 Deleted 且类型实现了软删除接口(如 IHasSoftDelete)的实体记得清除原 Deleted 状态并设为 Modified,否则 EF 仍会生成 DELETE 语句注意并发:如果同一实体在拦截前已被其他逻辑标记为 IsDeleted = true,重复设置可能触发无意义更新IgnoreQueryFilters 是绕过软删除的唯一合法方式,但要用对地方有些场景确实需要查“全部”,比如回收站页面、后台数据修复、或导出报表。这时不能删 HasQueryFilter,也不能临时改模型配置,唯一正确做法是调用 IgnoreQueryFilters() 方法。 文心快码 文心快码(Comate)是百度推出的一款AI辅助编程工具
更多推荐

所有评论(0)