日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

给 EF Core 查询增加 With NoLock

發布時間:2023/12/4 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 给 EF Core 查询增加 With NoLock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

給 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。