EF Core拦截器获取或修改SQL语句
最近在看EF Core官方文档时,发现有个叫拦截器的东西,那么这个拦截器有啥用呢?其实,一般情况下,我们可能也有用不到它。当我们需要操作EF Core执行的SQL语句或者操作数据库时,那么,拦截器就派上用场了。
在开始之前,我们先来认识三个拦截器接口
接口名 | 用途 | 基类 |
---|---|---|
IDbCommandInterceptor | 创建命令、执行命令、命令失败、释放命令的 DbDataReader | DbCommandInterceptor |
IDbConnectionInterceptor | 打开、关闭连接、连接失败 | DbConnectionInterceptor |
IDbTransactionInterceptor | 创建事务、使用现有事务、提交事务、回滚事务、创建和使用保存点、事务失败 | DbTransactionInterceptor |
基类包含对应接口中每个方法的实现。使用基类,则可以不需要实现每个接口方法。如果,我们想要获取执行的SQL语句,那么继承DbCommandInterceptor
这个基类即可。这里,我们先写个简单的取数接口,来看看EF Core生成的默认SQL语句是什么样的
1 | public IEnumerable<User> Get() |
我们知道First
和FirstOrDefault
是取一条数据,但是现在偏要让前面多条查询只返回一条数据呢。这里,我们就新建一个拦截器
继承DbCommandInterceptor
这个基类,并重写ReaderExecuting
方法
1 | public class ModifyDbCommandInterceptor: DbCommandInterceptor |
然后用AddInterceptors
来注册我新加的拦截器
1 | var serverVersion = new MySqlServerVersion(new Version(8, 0, 24)); |
上图可以看到,我们修改的SQL产生了效果,当然,正常情况下肯定没人会这般无聊。那么什么时候,我们可能会用到拦截器呢?我大致想到这几种场景,如:改写SQL,有时候,EF Core生成的SQL可能不是我们想要的;缓存结果数据,有时候,我们可能想将查询的结果数据缓存起来。当然,通过其他方式来缓存查询结果也可以;审计操作日志,有时候,我们想要记录增删改的日志,等等。
EF Core拦截器获取或修改SQL语句