Entity Framework Core怎么实现软删除 EF Core全局查询过滤器用法
发布时间 - 2025-12-30 00:00:00 点击率:次EF Core软删除通过全局查询过滤器自动添加IsDeleted==false条件并重写SaveChanges将Deleted状态改为Modified来实现。需定义ISoftDelete接口和BaseEntity基类,批量配置过滤器,慎用IgnoreQueryFilters()。
EF Core 实现软删除,核心是配合 全局查询过滤器(Global Query Filters) 自动对所有查询添加条件(如 IsDeleted == false),同时在删除操作中不真正删数据,而是标记为已删除。关键在于配置一致、避免绕过、注意导航属性和显式加载的兼容性。
定义软删除接口和实体基类
统一管理软删除字段,便于复用和约束:
- 定义接口
ISoftDelete,含IsDeleted和可选的DeletedAt属性 - 让需要软删除的实体继承一个基类(如
BaseEntity),实现该接口 - 确保数据库字段对应(如
IsDeleted类型为bit或boolean)
示例:
public interface ISoftDelete{
bool IsDe
leted { get; set; }DateTime? DeletedAt { get; set; }
}
public abstract class BaseEntity : ISoftDelete
{
public bool IsDeleted { get; set; }
public DateTime? DeletedAt { get; set; }
}
在 DbContext 中配置全局查询过滤器
在 OnModelCreating 中为每个支持软删除的实体启用过滤器:
- 使用
modelBuilder.Entity().HasQueryFilter(x => !x.IsDeleted) - 推荐用泛型方式批量注册,避免漏配;可用反射扫描继承自
BaseEntity的类型 - 过滤器会在所有 LINQ 查询(包括
Include导航属性)中自动生效
示例(手动配置):
protected override void OnModelCreating(ModelBuilder modelBuilder){
modelBuilder.Entity
modelBuilder.Entity
}
重写 Delete 方法实现软删除逻辑
EF Core 默认调用 Remove() 会触发物理删除,需改为更新状态:
- 重写
SaveChanges/SaveChangesAsync,扫描待删除实体,将其标记为IsDeleted = true,并取消物理删除操作 - 将实体状态从
Deleted改为Modified,仅更新软删除字段 - 注意:需排除已真正删除(如系统日志等不需要软删)的实体类型
示例片段:
public override int SaveChanges(bool acceptAllChangesOnSuccess){
foreach (var entry in ChangeTracker.Entries
{
if (entry.State == EntityState.Deleted)
{
entry.State = EntityState.Modified;
entry.CurrentValues["IsDeleted"] = true;
entry.CurrentValues["DeletedAt"] = DateTime.UtcNow;
}
}
return base.SaveChanges(acceptAllChangesOnSuccess);
}
绕过过滤器的场景与安全处理
某些业务需要查“已删除”数据(如回收站),EF Core 提供 IgnoreQueryFilters():
- 仅限可信上下文使用,例如后台管理页,避免暴露给前端随意调用
- 注意:它会跳过所有过滤器(不止软删除),慎用于包含多过滤器的模型
- 也可用
AsNoTrackingWithIdentityResolution()配合,但不推荐替代过滤器绕过
示例:
var deletedUsers = context.Users.IgnoreQueryFilters()
.Where(u => u.IsDeleted)
.ToList();
基本上就这些。全局过滤器 + 状态拦截是 EF Core 软删除最稳妥的组合,既保持代码简洁,又避免业务层遗漏判断。注意测试导航查询、显式加载和批量操作是否符合预期。
# 前端
# Boolean
# if
# foreach
# include
# bool
# int
# void
# 继承
# 接口
# class
# public
# protected
# Interface
# 泛型
# var
# delete
# 数据库
# linq
# 重写
# 加载
# 不需要
# 会在
# 将其
# 可选
# 仅限
# 但不
# 它会
# 来实现
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Android滚轮选择时间控件使用详解
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
如何解决hover在ie6中的兼容性问题
如何用IIS7快速搭建并优化网站站点?
如何快速上传自定义模板至建站之星?
微信小程序 require机制详解及实例代码
独立制作一个网站多少钱,建立网站需要花多少钱?
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
香港服务器如何优化才能显著提升网站加载速度?
海南网站制作公司有哪些,海口网是哪家的?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
如何快速查询网址的建站时间与历史轨迹?
Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
零基础网站服务器架设实战:轻量应用与域名解析配置指南
微信小程序 scroll-view组件实现列表页实例代码
无锡营销型网站制作公司,无锡网选车牌流程?
🚀拖拽式CMS建站能否实现高效与个性化并存?
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
Linux系统命令中tree命令详解
如何在云指建站中生成FTP站点?
大连网站制作公司哪家好一点,大连买房网站哪个好?
网站制作软件免费下载安装,有哪些免费下载的软件网站?
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
长沙做网站要多少钱,长沙国安网络怎么样?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
JavaScript Ajax实现异步通信
详解Oracle修改字段类型方法总结
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
Laravel Fortify是什么,和Jetstream有什么关系
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
如何在宝塔面板创建新站点?
深圳网站制作的公司有哪些,dido官方网站?
JavaScript如何实现类型判断_typeof和instanceof有什么区别
Laravel storage目录权限问题_Laravel文件写入权限设置
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
打开php文件提示内存不足_怎么调整php内存限制【解决方案】
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
,怎么在广州志愿者网站注册?
Python文件异常处理策略_健壮性说明【指导】
*服务器网站为何频现安全漏洞?
使用豆包 AI 辅助进行简单网页 HTML 结构设计
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
如何在IIS中新建站点并配置端口与物理路径?
如何基于PHP生成高效IDC网络公司建站源码?

