给 EF Core 查询增加 With NoLock

Intro

EF Core 在 3.x 版本中增加了 Interceptor,使得我们可以在发生低级别数据库操作时作为 EF Core 正常运行的一部分自动调用它们。例如,打开连接、提交事务或执行命令时。

所以我们可以自定义一个 Interceptor 来记录执行的 sql 语句,也可以通过 Interceptor 来实现 sql 语句的执行。

这里我们可以借助 Interceptor 实现对于查询语句的修改,自动给查询语句加 (WITH NOLOCK)WITH NOLOCK 等效于 READ UNCOMMITED(读未提交)的事务级别,这样会造成一定的脏读,但是从效率上而言,是比较高效的,不会因为别的事务长时间未提交而导致查询阻塞,所以对于大数据场景下,查询 SQL 加 NOLOCK 还是比较有意义的

NoLockInterceptor

继承 DbCommandInterceptor,重写查询 sql 执行之前的操作,在执行 sql 之前增加 WITH(NOLOCK),实现代码如下:

public class QueryWithNoLockDbCommandInterceptor : DbCommandInterceptor
{private static readonly Regex TableAliasRegex =new Regex(@"(?<tableAlias>AS \[[a-zA-Z]\w*\](?! WITH \(NOLOCK\)))",RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);public override InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<object> result){command.CommandText = TableAliasRegex.Replace(command.CommandText,"${tableAlias} WITH (NOLOCK)");return base.ScalarExecuting(command, eventData, result);}public override Task<InterceptionResult<object>> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<object> result,CancellationToken cancellationToken = new CancellationToken()){command.CommandText = TableAliasRegex.Replace(command.CommandText,"${tableAlias} WITH (NOLOCK)");return base.ScalarExecutingAsync(command, eventData, result, cancellationToken);}public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result){command.CommandText = TableAliasRegex.Replace(command.CommandText,"${tableAlias} WITH (NOLOCK)");return result;}public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result,CancellationToken cancellationToken = new CancellationToken()){command.CommandText = TableAliasRegex.Replace(command.CommandText,"${tableAlias} WITH (NOLOCK)");return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);}
}

Interceptor 的使用

在注册 DbContext 服务的时候,可以配置 Interceptor,配置如下:

var services = new ServiceCollection();
services.AddDbContext<TestDbContext>(options =>
{options.UseLoggerFactory(loggerFactory).UseSqlServer(DbConnectionString).AddInterceptors(new QueryWithNoLockDbCommandInterceptor());
});

使用效果

通过 loggerFactory 记录的日志查看查询执行的 sql 语句

可以看到查询语句自动加上了 WITH(NOLOCK)

Reference

  • https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver15

  • https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/#interception-of-database-operations

  • https://docs.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-3.0/#interception-of-database-operations

  • https://github.com/WeihanLi/WeihanLi.EntityFramework/blob/dev/src/WeihanLi.EntityFramework/Interceptors/QueryWithNoLockDbCommandInterceptor.cs

给 EF Core 查询增加 With NoLock相关推荐

  1. 讨论过后而引发对EF 6.x和EF Core查询缓存的思考

    前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过这个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...

  2. ef 多个左联接查询_.NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记...

    2.4.5 EF Core -- 查询 关联数据加载 客户端与服务端运算 跟踪与不跟踪 复杂查询运算 原生 SQL 查询 全局查询筛选器 关联数据加载 学员和助教都在项目分组中,调整模型,删除 Ass ...

  3. .NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记

    2.4.5 EF Core -- 查询 关联数据加载 客户端与服务端运算 跟踪与不跟踪 复杂查询运算 原生 SQL 查询 全局查询筛选器 关联数据加载 学员和助教都在项目分组中,调整模型,删除 Ass ...

  4. EF Core查询标签TagWith

    概述 在使用EF Core的时候,有时候我们需要追踪它生成的sql语句,那么方法那么多,我们怎么知道对应的sql语句是在代码哪里呢,这时候就需要一个备注, TagWith()能够帮助我们生成对应的注释 ...

  5. 查缺补漏系统学习 EF Core 6 - 数据查询

    这是 EF Core 系列的第四篇文章,上一篇文章讲述了 EF Core 中的实体迁移与数据播种. 这篇文章盘点一下 EF Core 的几种数据查询方式,内容较多分上下两篇. 点击上方或后方蓝字,阅读 ...

  6. [翻译 EF Core in Action 2.3] 理解EF Core数据库查询

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  7. 查缺补漏系统学习 EF Core 6 - 原始 SQL 查询

    推荐关注「码侠江湖」加星标,时刻不忘江湖事 这是 EF Core 系列的第五篇文章,上一篇文章盘点了 EF Core 中的几种数据查询方式. 但是有有时候,我们可能无法用标准的 LINQ 方法完成查询 ...

  8. EF Core的学习之路01

    本文章是我听B站杨中科的所做的笔记 杨中科B站视频链接:.NET 6教程,.Net Core 2022视频教程,杨中科主讲_哔哩哔哩_bilibili 什么时ORM 1.说明:本课程需要你有数据库.S ...

  9. EntityFramework Core 3.x添加查询提示(NOLOCK)

    前几天看到有博客园中有园友写了一篇关于添加NOLOCK查询提示的博文,这里呢,我将介绍另外一种添加查询提示的方法,此方式源于我看过源码后的实现,孰好孰歹,请自行判之,接下来我们一起来看看. 在Enti ...

最新文章

  1. 【重磅】斯坦福李飞飞《注意力与Transformer》总结,84页ppt开放下载!
  2. 撞库攻击:一场需要用户参与的持久战
  3. java实现线程间通信的四种方式
  4. gets scanf以及缓冲区域的问题
  5. java中的list时间排序
  6. 【深度学习】深入理解卷积神经网络(CNN)
  7. oracle和mysql通用建表语句_mysql建表语句到oracle怎么写?
  8. 使用HTML5创建和播放声音
  9. 10A 的GROUP和CUI使用
  10. 使用Jasypt加密spring boot应用配置文件的敏感信息
  11. 学生物的女朋友都能看懂的哈希表总结!
  12. Vue:结合ElementUI元素超过一定高度加滚动框,高度由浏览器高度决定并随浏览器变化而变化
  13. C++ for (auto it:myset) 是什么意思 引用
  14. ubuntu linux运行exe文件,Linux Ubuntu 打开.exe文件
  15. 前端高级——Node的变迁
  16. android 半圆型菜单,Android-自定义view之圆形与“半圆形”菜单
  17. 清橙OJ A1035 素数之和
  18. 动图图解!既然IP层会分片,为什么TCP层也还要分段?
  19. html背景图片不重叠铺满,css背景图片怎么铺满
  20. 详解液晶面板制造全过程

热门文章

  1. 去除HTML标签--SQL写法
  2. PHP个人博客项目------切切歆语博客
  3. 【软件周刊】D语言卷土重来,Vue.js 应获 1024 个赞,小薇可以一键启动了
  4. Xamarin.Android和UWP之MVVM的简单使用(二)
  5. Linux 下用来查询安装包信息的RPM选项
  6. 如何扩展开发团队(转)
  7. 北京点击科技有限公司董事长兼总裁——王志东经典语录2
  8. #抵抗3#(#Resistance 3#) 绝对值得体验的冒险历程
  9. 使用ClickOnce部署VS2005中的WinForm应用程序.(ZT)
  10. 右击硬盘分区第一项出现Auto的解决办法