EF Core SaveChanges拦截器怎么用 EF Core ISaveChangesInterceptor教程

来源:这里教程网 时间:2026-02-21 17:35:04 作者:

SaveChanges拦截器是干什么的

它是在调用

SaveChanges
SaveChangesAsync
前后自动触发的钩子,不用改DbContext代码就能统一处理数据变更逻辑。比如自动填充创建/更新时间、记录谁改了数据、做业务校验、写审计日志,甚至临时阻止非法保存。

怎么注册一个SaveChangesInterceptor

在DI容器配置DbContext时,用

AddInterceptors
方法注入实现类:

ASP.NET Core常规项目中,在
Program.cs
里这样写:

services.AddDbContext(options =>
  options.UseSqlServer(connectionString)
  .AddInterceptors(new AuditSaveChangesInterceptor()));

Aspire项目需用
ConfigureDbContext
避免服务解析问题:

builder.ConfigureDbContext((provider, options) =>
  options.AddInterceptors(provider.GetRequiredService()));

怎么写一个基础的拦截器

实现

ISaveChangesInterceptor
接口,重点关注两个方法:

SavingChanges:保存前触发,可修改实体状态、校验、或直接
SuppressWithResult
中断保存
SavedChanges:保存成功后触发,适合发通知、记日志、清理缓存

示例:自动设置

UpdatedAt
字段

public class AuditSaveChangesInterceptor : ISaveChangesInterceptor
{
  public InterceptionResult SavingChanges(DbContextEventData eventData, InterceptionResult result)
  {
    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会跳过后续操作——这适合做权限拦截或软删除替代。

基本上就这些。

相关推荐