SaveChanges拦截器是在调用SaveChanges或SaveChangesAsync前后自动触发的钩子,用于统一处理数据变更逻辑,如自动填充时间戳、审计日志、业务校验或阻止非法保存;通过AddInterceptors注册,实现ISaveChangesInterceptor接口的SavingChanges(保存前)和SavedChanges(保存后)方法。

SaveChanges拦截器是干什么的
它是在调用SaveChanges或SaveChangesAsync前后自动触发的钩子,不用改DbContext代码就能统一处理数据变更逻辑。比如自动填充创建/更新时间、记录谁改了数据、做业务校验、写审计日志,甚至临时阻止非法保存。
怎么注册一个SaveChangesInterceptor
在DI容器配置DbContext时,用AddInterceptors方法注入实现类:
- ASP.NET Core常规项目中,在
Program.cs里这样写:
services.AddDbContext
options.UseSqlServer(connectionString)
.AddInterceptors(new AuditSaveChangesInterceptor()));
- Aspire项目需用
ConfigureDbContext避免服务解析问题:
builder.ConfigureDbContext
options.AddInterceptors(provider.GetRequiredService
怎么写一个基础的拦截器
实现ISaveChangesInterceptor接口,重点关注两个方法:
-
SavingChanges:保存前触发,可修改实体状态、校验、或直接
SuppressWithResult中断保存 - SavedChanges:保存成功后触发,适合发通知、记日志、清理缓存
示例:自动设置UpdatedAt字段
public class AuditSaveChangesInterceptor : ISaveChangesInterceptor
{
public InterceptionResult
{
var context = eventData.Context;
if (context != null)
{
var entries = context.ChangeTracker.Entries
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
foreach (var entry in entries)
{
if (entry.State == EntityState.Added)
entry.Entity.CreatedAt = DateTime.UtcNow;
entry.Entity.UpdatedAt = DateTime.UtcNow;
}
}
return result;
}
public void SavedChanges(DbContextEventData eventData, int result)
{
// 可在此处记录日志,比如“共保存5条记录”
}
}
常见注意点
拦截器是无状态的,别在类里存实例字段;如需依赖服务(如ILogger),通过构造函数注入;多个拦截器按注册顺序执行;若在SavingChanges中返回带结果的InterceptionResult,EF会跳过后续操作——这适合做权限拦截或软删除替代。
基本上就这些。










