网上的方案https://blog.csdn.net/sD7O95O/article/details/105320673,有点小问题,正则表达式不支持子查询;
略作修改。
using Microsoft.EntityFrameworkCore.Diagnostics; using System; using System.Collections.Generic; using System.Data.Common; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; public class QueryWithNoLockDbCommandInterceptor : DbCommandInterceptor { private static readonly Regex TableAliasRegex = new Regex(@"(?<tableAlias>(FROM|JOIN) [[a-zA-Z]w*] 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 ValueTask<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 ValueTask<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); } }
dbcontext上加上这个拦截器
var services = new ServiceCollection(); services.AddDbContext<TestDbContext>(options => { options .UseLoggerFactory(loggerFactory) .UseSqlServer(DbConnectionString) .AddInterceptors(new QueryWithNoLockDbCommandInterceptor()) ; });