信息发布→ 登录 注册 退出

EF Core如何实现软删除 EF Core软删除查询过滤器方法

发布时间:2026-01-04

点击量:
EF Core软删除核心是用查询过滤器自动屏蔽IsDeleted为true的数据,需添加IsDeleted字段、配置HasQueryFilter、重写SaveChanges将Delete转为Update,并可用IgnoreQueryFilters临时绕过。

EF Core 实现软删除,核心是用 查询过滤器(Query Filter) 自动屏蔽已标记为“删除”的数据,而不是真正从数据库删掉。它不依赖手写 .Where(!x.IsDeleted),而是让每次查询都透明生效——既安全又省心。

加一个 IsDeleted 字段

在要支持软删除的实体类里,添加布尔类型的标记属性:

  • 推荐命名为 IsDeleted,类型为 bool,默认值设为 false
  • 如果需要记录删除时间或操作人,可额外加 DeletedAtDeletedBy 字段
  • 不要对一对一关联实体单独软删除,容易引发导航属性异常

在 DbContext 中配置查询过滤器

重写 OnModelCreating 方法,为实体启用全局过滤:

  • 基础写法:modelBuilder.Entity().HasQueryFilter(p => !p.IsDeleted);
  • 字段存为整数(如数据库用 TINYINT)?加上值转换:.Property(e => e.IsDeleted).HasConversion()
  • 多个实体统一处理?可用反射遍历实现 IDeletable 接口的类型,自动注册过滤器

覆盖删除行为:把 Delete 变成 Update

调用 Remove() 时,EF 默认会生成 DELETE SQL。要改成软删除,得拦截保存前的操作:

  • 重写 SaveChangesSaveChangesAsync
  • 遍历 ChangeTracker.Entries(),对 EntityState.Deleted 的条目改为 Modified,并把 IsDeleted 设为 true
  • 新增数据时确保 IsDeleted 默认为 false(可在 Added 分支中设置)

需要查已删除数据?临时绕过过滤器

管理后台或恢复功能常需看到全部记录,这时可以用:

  • context.Posts.IgnoreQueryFilters().Where(p => p.IsDeleted).ToList()
  • 注意:IgnoreQueryFilters() 会跳过该实体上所有过滤器,不只是软删除那个
  • 如需更灵活控制(比如只在某些场景下包含已删数据),建议构造不同 DbContext 实例,或通过构造函数传入开关参数

基本上就这些。不复杂但容易忽略细节,比如没改 SaveChanges 行为会导致物理删除,或者忘了给关联实体配过滤器导致数据不一致。

标签:# 重写  # 如需  # 只在  # 要对  # 布尔  # 可在  # 可以用  # 多个  # 设为  # 遍历  # sql  # 数据库  # delete  # Property  # 布尔类型  # 接口  # int  # bool  # Filter  # 构造函数  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!