C# entityframework生成sql語句添加with(nolock)最優(yōu)解決方案
/// <summary> /// ef實現(xiàn)withnolock,給表名后面添加with(nolock),不適用.net core /// </summary> public class WithNoLockInterceptor : DbCommandInterceptor { private static readonly Regex TableAliasRegex = new Regex(@"(?<tableAlias>\[dbo\].\[\w+\] AS \[Extent\d+\](?! WITH\(NOLOCK\)))", RegexOptions.Multiline | RegexOptions.IgnoreCase); /// <summary> /// https://www.bbsmax.com/A/8Bz8V6V65x/ /// 建議不要為標(biāo)記為 ThreadStaticAttribute 的字段指定初始值,因為這樣的初始化只會發(fā)生一次,因此在類構(gòu)造函數(shù)執(zhí)行時只會影響一個線程。 /// 在不指定初始值的情況下,如果它是值類型,可依賴初始化為其默認(rèn)值的字段,如果它是引用類型,則可依賴初始化為空引用的字段。 /// </summary> [ThreadStatic] public static bool Uselocking; [ThreadStatic] public static string CommandText; public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { if (!Uselocking) { command.CommandText = TableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH(NOLOCK) "); CommandText = command.CommandText; } //System.IO.File.AppendAllText("D:\\1.txt", "Uselocking=" + Uselocking.ToString() + "~" + CommandText + "\r\n\r\n"); } public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { if (!Uselocking) { command.CommandText = TableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH(NOLOCK) "); CommandText = command.CommandText; } //System.IO.File.AppendAllText("D:\\1.txt", "Uselocking=" + Uselocking.ToString() + "~" + CommandText + "\r\n\r\n"); }
使用:在Global.cs的Application_Start()里面添加如下語句,生成的sql會自動加上with(nolock)
//ef命令攔截器
DbInterception.Add(new WithNoLockInterceptor());
如果執(zhí)行的sql語句需要鎖表,增加如下擴(kuò)展即可
public static class WithNoLockExtensions { /// <summary> /// 部分查詢需要使用鎖查詢的,可以調(diào)用此擴(kuò)展(默認(rèn)全局查詢使用with(nolock)) /// 參考:https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1637/ /// 示例: /// 1、query.OrderByCustom(filters.orderFields).Select({...}).UseLocking(querable => querable.PagingAsync(filters.page, filters.rows)); /// 2、repository.EntitiesAsNoTracking.Select(...).UseLocking(item=>item.FirstOrDefaultAsync()); /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="query"></param> /// <param name="queryAction"></param> /// <returns></returns> public static TResult UseLocking<T, TResult>(this IQueryable<T> query, Func<IQueryable<T>, TResult> queryAction) { WithNoLockInterceptor.Uselocking = true; //System.IO.File.AppendAllText("D:\\2.txt", $"更改了Uselocking{WithNoLockInterceptor.Uselocking}狀態(tài)\r\n\r\n"); TResult queryableResult = default(TResult); try { queryableResult = queryAction(query); } finally { WithNoLockInterceptor.Uselocking = false; } //System.IO.File.AppendAllText("D:\\2.txt", $"更改了Uselocking2{WithNoLockInterceptor.Uselocking}狀態(tài)\r\n\r\n"); return queryableResult; }
1、修復(fù)了網(wǎng)上提供的正則表達(dá)式特殊情況下報錯問題

浙公網(wǎng)安備 33010602011771號