河南新乡地 图[:给 EF Core 查询增加 With NoLock

admin 4周前 (08-30) 科技 50 1

「进入」sunbet〖官网手机版登〗陆

欢迎「进入」sunbet〖官网手机版登〗陆!Sunbet 【申博提供申博(开)户】(sunbet(开)户)、SunbetAPP(下载)、Sunbet客户端(下载)、Sunbet{代理合作等业务}。

,

〖给〗 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
Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:河南新乡地 图[:给 EF Core 查询增加 With NoLock

网友评论

  • (*)

最新评论

  • AllbetGmaing客户端下载 2020-08-30 00:00:56 回复

    欧博亚洲欢迎进入欧博亚洲(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。已入坑,出不来了

    1

标签列表

    文章归档

      站点信息

      • 文章总数:621
      • 页面总数:0
      • 分类总数:8
      • 标签总数:995
      • 评论总数:254
      • 浏览总数:9141