给 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. DataGirdView

    DataGridView知识点 简单示例 (1)代码 SqlDataAdapter da; DataSet ds; string sql ="select 列名 from 表名": ...

  2. 54-with管理文件操作上下文

    目录 with管理文件操作上下文 with管理文件操作上下文 之前我们使用open()方法操作文件,但是open打开文件后我们还需要手动释放文件对操作系统的占用.其实我们可以更方便的打开文件,即Pyt ...

  3. 简单说 用CSS做一个魔方旋转的效果

    说明 魔方大家应该是不会陌生的,这次我们来一起用CSS实现一个魔方旋转的特效,先来看看效果图! 解释 我们要做这样的效果,重点在于怎么把6张图片,摆放成魔方的样子,而把它们摆放成魔方的样子,重点在于用 ...

  4. 前端每日实战:111# 视频演示如何用纯 CSS 创作一只艺术的鸭子

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/aaoveW 可交互视频 此视频是可 ...

  5. 响应式导航菜单(css+js)

    1.响应式导航菜单 先来看下效果图把: 当视口大于640px的时候,导航条会显示在外,当视口小于768px的时候,导航菜单需要隐藏起来!代码如下: <!doctype html> < ...

  6. Python 三程三器的那些事

    装饰器 1.什么是装饰器 装饰器本质是函数,用来给其他函数添加新的功能 特点:不修改调用方式.不修改源代码 2.装饰器的作用 装饰器作用:本质是函数(装饰其他函数)就是为其他函数添加其他功能 装饰器必 ...

  7. 一起了解 .Net Foundation 项目 No.16

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Orchard CMS O ...

  8. python3编写程序,实现打印100以内的素数。

    代码如下: for x in range(2, 100): for y in range(2, x): if x % y == 0: break else: print(x, end="\t ...

  9. openwrt 外挂usb 网卡 RTL8188CU 及添加 RT5572 kernel支持

    RT5572 原来叫 Ralink雷凌 现在被 MTK 收购了,淘宝上买的很便宜50块邮,2.4 5G 双频.在 win10 上插了试试,果然是支持 5G.这上面写着 飞荣 是什么牌子,有知道的和我说 ...

  10. selenium基本对象之——数值型

    python的数值类型,除了魔法方法以为,只有下面的这些方法: 整形的方法有:as_integer_ratio.bit_length.from_bytes.to_bytes.conjugate.ima ...