using Microsoft.EntityFrameworkCore.Diagnostics; using System.Data.Common; using System.Text.RegularExpressions; namespace Masuit.Tools.Core; public class QueryWithNoLockDbCommandInterceptor : DbCommandInterceptor { private static readonly Regex TableAliasRegex = new Regex(@"(?AS \[[a-zA-Z]\w*\](?! WITH \(NOLOCK\)))", RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase); public override InterceptionResult ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return base.ScalarExecuting(command, eventData, result); } #if NETCOREAPP3_1 public override Task> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = new CancellationToken()) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return base.ScalarExecutingAsync(command, eventData, result, cancellationToken); } #else public override ValueTask> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = new CancellationToken()) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return base.ScalarExecutingAsync(command, eventData, result, cancellationToken); } #endif public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return result; } #if NETCOREAPP3_1 public override Task> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = new CancellationToken()) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return base.ReaderExecutingAsync(command, eventData, result, cancellationToken); } #else public override ValueTask> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = new CancellationToken()) { command.CommandText = TableAliasRegex.Replace( command.CommandText, "${tableAlias} WITH (NOLOCK)" ); return base.ReaderExecutingAsync(command, eventData, result, cancellationToken); } #endif }