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在 OnModel 中为每个支持软删除的实体启用过滤器:
Creating
modelBuilder.Entity().HasQueryFilter(x => !x.IsDeleted)
BaseEntity 的类型Include 导航属性)中自动生效示例(手动配置):
protected override void OnModelCreating(ModelBuilder modelBuilder)EF Core 默认调用 Remove() 会触发物理删除,需改为更新状态:
SaveChanges / SaveChangesAsync,扫描待删除实体,将其标记为 IsDeleted = true,并取消物理删除操作Deleted 改为 Modified,仅更新软删除字段示例片段:
public override int SaveChanges(bool acceptAllChangesOnSuccess)某些业务需要查“已删除”数据(如回收站),EF Core 提供 IgnoreQueryFilters():
AsNoTrackingWithIdentityResolution() 配合,但不推荐替代过滤器绕过示例:
var deletedUsers = context.Users基本上就这些。全局过滤器 + 状态拦截是 EF Core 软删除最稳妥的组合,既保持代码简洁,又避免业务层遗漏判断。注意测试导航查询、显式加载和批量操作是否符合预期。