0

0

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

星降

星降

发布时间:2025-12-23 11:40:03

|

148人浏览过

|

来源于php中文网

原创

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

ef core savechanges拦截器怎么用 ef core isavechangesinterceptor教程

SaveChanges拦截器是干什么的

它是在调用SaveChangesSaveChangesAsync前后自动触发的钩子,不用改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接口,重点关注两个方法:

VisualizeAI
VisualizeAI

用AI把你的想法变成现实

下载
  • 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会跳过后续操作——这适合做权限拦截或软删除替代。

基本上就这些。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

436

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

738

2023.08.22

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

42

2025.12.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

537

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 46.4万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号