给 EF Core 查询增加 With NoLock

Intro

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

所以我们可以自定义一个 Interceptor 来记录执行的 sql 语句,也可以通过 Interceptor 来实现 sql 语句的执行前的修改或者更准确的记录 DbCommand 执行的耗时。

这里我们可以借助 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

给 EF Core 查询增加 With NoLock的更多相关文章

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

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

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

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

  3. [翻译 EF Core in Action 2.0] 查询数据库

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

  4. EF Core中Join可以进行子查询

    我们来看看下面的代码,这个代码是一个INNER JOIN的EF Core查询,其中用SubCategory表INNER JOIN了SubCategoryLanguage表,但是我们需要在SubCate ...

  5. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  6. EF Core 快速上手——EF Core的三种主要关系类型

    系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询   本 ...

  7. EF Core 数据过滤

    1 前言 本文致力于将一种动态数据过滤的方案描述出来(基于 EF Core 官方的数据筛选器),实现自动注册,多个条件过滤,单条件禁用(实际上是参考ABP的源码),并尽量让代码保持 EF Core 的 ...

  8. 好大一个坑: EF Core 异步读取大字符串字段比同步慢100多倍

    这两天遇到一个奇怪的问题,通过 EF/EF Core 查询数据库速度奇慢,先是在传统的 ASP.NET 项目中遇到(用的是EF6.0),后来将该项目迁移至 ASP.NET Core 也是同样的问题(用 ...

  9. EF Core 6.0的新计划

    今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...

随机推荐

  1. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.2)- FlexSPI NOR连接方式大全(RT1060/1064(SIP))

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1060/1064(SIP)两款MCU的FlexSPI NOR启动的连接方式. 上一篇文章<FlexSPI N ...

  2. 利用matplotlib进行数据可视化

    matplotlib是python中的一个画图库,继承了matlib(从名字上也看得出来)的优点和语法,所以对于熟悉matlib的用户来说是十分友好的. pylab和pyplot 关于pylab和py ...

  3. VMware安装CentOS6.X 系统

    1.虚拟机中的"CD/DVD(IDE)"配置好Linux映像文件后,打开虚拟机,点击"开启此虚拟机" 2.进入光盘启动界面,选择第一项,表示安装升级Linux系 ...

  4. 《自拍教程36》段位三_Python面向对象类

    函数只能面向过程,来回互相调用后顺序执行, 简单的编码项目,还能应付的过来, 复杂的大型项目,调用多了,就会乱. 如何才能不乱呢,可尝试下, 面向对象类的概念, 将现实世界的事物抽象成对象,将现实世界 ...

  5. html+css布局类型

    一.单列布局 1.代码如下 <!doctype html> <html> <head> <meta charset="utf-8"/> ...

  6. jdk1.5之后,classpath不需要再配置

    1.5之后更智能了. 设置了classpath之后,当前目录失效(在classpath中没找到就报错,不会再在当前目录继续找),所以要把当前目录添加到classpath,永久环境变量添加 .,临时环境 ...

  7. Dubbo进阶

    注册中心zookeeper 什么是注册中心: 注册中心就是用来存储服务信息的地方,就像房屋中介一样; 为什么需要注册中心: 在前面的例子中我们使用了客户端与服务器直连的方式完成了服务的调用,在实际开发 ...

  8. proteus pro 8.9 安装及汉化教程

    最近由于网上上课老师要求我们自己安装proteus这款仿真软件,所以笔者也安装了最新款版的proteus pro 8.9,分享给大家安装心得,也包含汉化过程,希望大家能用软件好好学习. 备注:感谢博主 ...

  9. jQuery上传文件按钮美化

    效果图如下: 思路: 1:打开文件设置为透明,外面包一层标签,给标签设置颜色背景,给人点击浏览其实是点击打开文件的错觉.(给外标签相对定位,打开文件标签绝对定位). 2:点击浏览后,选择了文件,就把文 ...

  10. jwt的token如何使用

    JWT简介: JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式).它是在Web环境下 ...