tnblog
首页
视频
资源
登录

给 EF Core 查询增加 With NoLock

3503人阅读 2023/4/10 15:33 总访问:430298 评论:0 收藏:0 手机
分类: EF

介绍

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),实现代码如下:

  1. public class QueryWithNoLockDbCommandInterceptor : DbCommandInterceptor
  2. {
  3. private static readonly Regex TableAliasRegex =
  4. new Regex(@"(?<tableAlias>AS \[[a-zA-Z]\w*\](?! WITH \(NOLOCK\)))",
  5. RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
  6. public override InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<object> result)
  7. {
  8. command.CommandText = TableAliasRegex.Replace(
  9. command.CommandText,
  10. "${tableAlias} WITH (NOLOCK)"
  11. );
  12. return base.ScalarExecuting(command, eventData, result);
  13. }
  14. public override Task<InterceptionResult<object>> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<object> result,
  15. CancellationToken cancellationToken = new CancellationToken())
  16. {
  17. command.CommandText = TableAliasRegex.Replace(
  18. command.CommandText,
  19. "${tableAlias} WITH (NOLOCK)"
  20. );
  21. return base.ScalarExecutingAsync(command, eventData, result, cancellationToken);
  22. }
  23. public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
  24. {
  25. command.CommandText = TableAliasRegex.Replace(
  26. command.CommandText,
  27. "${tableAlias} WITH (NOLOCK)"
  28. );
  29. return result;
  30. }
  31. public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result,
  32. CancellationToken cancellationToken = new CancellationToken())
  33. {
  34. command.CommandText = TableAliasRegex.Replace(
  35. command.CommandText,
  36. "${tableAlias} WITH (NOLOCK)"
  37. );
  38. return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
  39. }
  40. }

Interceptor 的使用

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

  1. var services = new ServiceCollection();
  2. services.AddDbContext<TestDbContext>(options =>
  3. {
  4. options
  5. .UseLoggerFactory(loggerFactory)
  6. .UseSqlServer(DbConnectionString)
  7. .AddInterceptors(new QueryWithNoLockDbCommandInterceptor())
  8. ;
  9. });

原文:https://www.cnblogs.com/weihanli/p/12623934.html

评价

范德萨

toke一个缓存,防止多次访问

Redis 缓存一个toke 代码如下:publicstaticstringGetToken() { RedisClientredisClient=newRedisClient(); //先从缓存...

.net core过滤器viewbag赋值

代码很简单,context.Controller是个object对象,需要自己转化成Controller即可,就可以使用Controller里边的东西了//先强...

c HttpClient webapi post接口传递一个参数。传递参数的同时传递一个cookie

webapi post传递一个参数是真的坑,有多坑,可以看看这篇文章:https://www.tnblog.net/aojiancc2/article/details/2874 ...

layuitable中的单选按钮添加点击事件

比如这样的一个表格其实用form.on就行了,里边接你需要监听事件的类型比如单选就是radio后面的premissonradio就是lay-filte...

有什么建议即将出国留学的学生?

1.学好英语有人肯定会纳闷了,为什么马上就要出国了,你还建议我学好英语呀。那是因为你雅思是考到6.5、7,但是当你初到国...

vue3,vue组件,props一个对象参数。vue组件间传参数vue父组件子组件传参数。组件参数类型。父组件调用子组件的方法。vue组件事件监听,子组件传递方法,子组件调用父组件方法

[TOC]组件可以使用props给组件传值,可以同时传递多个,可以是任意类型,比如字符串或者对象。 下面是个简单的例子: &lt...

后台返回json数据前台和前台解析json数据(总结)

前言:hello 大家好,我是小付,今天给大家分享的是后台返回json数据给前台和前台解析json数据,让我们一起来看看吧! 一般...

js不同用户随机显示不同颜色

彼年豆蔻,谁许谁地老天荒。首先js随机产生颜色思路就是随机产生6个16进制的数字即可//js随机产生颜色 functionrandomColo...

笔记本共享外网络台式机上网

笔记本共享外网络给台式机上网提示:我们都知道,台式电脑是不可以连接WiFi的,除非通过WiFi驱动器外接设备进行使用!那么...

输入的值添加约束

publicpartialclassUserInfo { publicintid{get;set;} [Required]//不能为空 [StringLength(12)]//控制输入字符的长度 ...

反射调用方法方法提供泛型,动态提供泛型参数

有些时候需要把泛型当做参数来进行传递,直接传递是不行的,这个时候我们就可以通过反射来调用。首先反射可以拿到某个属性...

.net方法动态提供泛型参数

有的时候需要把泛型当做参数来进行传递,直接传递是不行的,这个时候我们就可以通过反射来调用。反射可以拿到某个属性的类...

反射调用泛型方法方法提供泛型

有些时候需要把泛型当做参数来进行传递,直接传递是不行的,这个时候我们就可以通过反射来调用。首先反射可以拿到某个属性...

core 统一 ViewBag 赋值,过滤器

.net core过滤器给viewbag赋值,统一设置方便到在布局页中获取//.netcore过滤器给viewbag赋值,统一设置方便到在布局页中获取...

Layui动态选中复选框,动态选中checkboxLayui表单赋值

Layui给表单赋值://给表单赋值 form.val(&quot;formTest&quot;,{//formTest即class=&quot;layui-form&quot;所在元素属性l...
吃亏决不亏,惜福才有福
排名
12
文章
74
粉丝
4
评论
15
ASP.NET中webform中的几个生命周期函数
修心 : 什么周期除了这些还有什么呢
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
人恰得亏,戏不好看。