• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#entityframework生成sql语句添加with(nolock)最优解决方案

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
/// <summary>
    /// ef实现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/
        /// 建议不要为标记为 ThreadStaticAttribute 的字段指定初始值,因为这样的初始化只会发生一次,因此在类构造函数执行时只会影响一个线程。
        /// 在不指定初始值的情况下,如果它是值类型,可依赖初始化为其默认值的字段,如果它是引用类型,则可依赖初始化为空引用的字段。
        /// </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());

如果执行的sql语句需要锁表,增加如下扩展即可

public static class WithNoLockExtensions
    {
        /// <summary>
        /// 部分查询需要使用锁查询的,可以调用此扩展(默认全局查询使用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}状态\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}状态\r\n\r\n");
            return queryableResult;
        }

 

 

1、修复了网上提供的正则表达式特殊情况下报错问题

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#远程调用技术WebService修炼手册发布时间:2022-07-13
下一篇:
C#缓存操作类发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap