给 EF Core 查询增加 With NoLock
给 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
- 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的更多相关文章
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
- [翻译 EF Core in Action 2.3] 理解EF Core数据库查询
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 2.0] 查询数据库
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- EF Core中Join可以进行子查询
我们来看看下面的代码,这个代码是一个INNER JOIN的EF Core查询,其中用SubCategory表INNER JOIN了SubCategoryLanguage表,但是我们需要在SubCate ...
- 深入理解 EF Core:使用查询过滤器实现数据软删除
原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...
- EF Core 快速上手——EF Core的三种主要关系类型
系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询 本 ...
- EF Core 数据过滤
1 前言 本文致力于将一种动态数据过滤的方案描述出来(基于 EF Core 官方的数据筛选器),实现自动注册,多个条件过滤,单条件禁用(实际上是参考ABP的源码),并尽量让代码保持 EF Core 的 ...
- 好大一个坑: EF Core 异步读取大字符串字段比同步慢100多倍
这两天遇到一个奇怪的问题,通过 EF/EF Core 查询数据库速度奇慢,先是在传统的 ASP.NET 项目中遇到(用的是EF6.0),后来将该项目迁移至 ASP.NET Core 也是同样的问题(用 ...
- EF Core 6.0的新计划
今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...
随机推荐
- DataGirdView
DataGridView知识点 简单示例 (1)代码 SqlDataAdapter da; DataSet ds; string sql ="select 列名 from 表名": ...
- 54-with管理文件操作上下文
目录 with管理文件操作上下文 with管理文件操作上下文 之前我们使用open()方法操作文件,但是open打开文件后我们还需要手动释放文件对操作系统的占用.其实我们可以更方便的打开文件,即Pyt ...
- 简单说 用CSS做一个魔方旋转的效果
说明 魔方大家应该是不会陌生的,这次我们来一起用CSS实现一个魔方旋转的特效,先来看看效果图! 解释 我们要做这样的效果,重点在于怎么把6张图片,摆放成魔方的样子,而把它们摆放成魔方的样子,重点在于用 ...
- 前端每日实战:111# 视频演示如何用纯 CSS 创作一只艺术的鸭子
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/aaoveW 可交互视频 此视频是可 ...
- 响应式导航菜单(css+js)
1.响应式导航菜单 先来看下效果图把: 当视口大于640px的时候,导航条会显示在外,当视口小于768px的时候,导航菜单需要隐藏起来!代码如下: <!doctype html> < ...
- Python 三程三器的那些事
装饰器 1.什么是装饰器 装饰器本质是函数,用来给其他函数添加新的功能 特点:不修改调用方式.不修改源代码 2.装饰器的作用 装饰器作用:本质是函数(装饰其他函数)就是为其他函数添加其他功能 装饰器必 ...
- 一起了解 .Net Foundation 项目 No.16
.Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Orchard CMS O ...
- python3编写程序,实现打印100以内的素数。
代码如下: for x in range(2, 100): for y in range(2, x): if x % y == 0: break else: print(x, end="\t ...
- openwrt 外挂usb 网卡 RTL8188CU 及添加 RT5572 kernel支持
RT5572 原来叫 Ralink雷凌 现在被 MTK 收购了,淘宝上买的很便宜50块邮,2.4 5G 双频.在 win10 上插了试试,果然是支持 5G.这上面写着 飞荣 是什么牌子,有知道的和我说 ...
- selenium基本对象之——数值型
python的数值类型,除了魔法方法以为,只有下面的这些方法: 整形的方法有:as_integer_ratio.bit_length.from_bytes.to_bytes.conjugate.ima ...