Database.Log 未从 Entity Framework 中的拦截器附加记录 SQL

Database.Log not logging appended SQL from interceptor in Entity Framework

我将下面的代码成功附加到从 Entity Framework 创建的 SQL 查询中,在范围内有一个拦截器,但是下面的 Database.Log ,之后调用,不显示OPTION(RECOMPILE) 在查询中,所以我不确定它是否被执行了。

调用代码

  using (new OptionRecompileScope(_divisionPoolsRepository.DataContext))
            {
                divisionTeamResultsIds.AddRange(_divisionPoolsRepository.DataContext.DivisionBracketParticipants.Where(g => g.DivisionBracketParticipantPool.DivisionPoolId == divisionPoolId.Value).Select(g => g.DivisionGameTeamResultId).Distinct().ToList());
            }

OptionRecompileScope.cs

private void AddOptionRecompile(IDbCommand command)
            {
                command.CommandText += " OPTION(RECOMPILE)";
            }

上面的代码来自这个linkEF 6 Parameter Sniffing

DataContext.cs

public class DataContext : DbContext
    {
        private readonly ILogger _logger;

        public DataContext(ILogger logger)
        {
            Database.SetInitializer<DataContext>(null);

            Configuration.LazyLoadingEnabled = false;
            Configuration.ProxyCreationEnabled = false;

            _logger = logger;

            if (Config.Debugging.LogDatabase)
            {
                Database.Log = q => _logger.Debug(q);
            }
        }
}

整个范围Class

public class OptionRecompileScope : IDisposable
    {
        private const string QueryHintText = " OPTION(RECOMPILE)";
        private readonly OptionRecompileDbCommandInterceptor interceptor;

        public OptionRecompileScope(DbContext context)
        {
            interceptor = new OptionRecompileDbCommandInterceptor(context);
            DbInterception.Add(interceptor);
        }

        public void Dispose()
        {
            DbInterception.Remove(interceptor);
        }

        private class OptionRecompileDbCommandInterceptor : IDbCommandInterceptor
        {
            private readonly DbContext dbContext;

            internal OptionRecompileDbCommandInterceptor(DbContext dbContext)
            {
                this.dbContext = dbContext;
            }

            public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
            {
            }

            public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
            {
            }

            public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
            {
                if (ShouldIntercept(command, interceptionContext))
                {
                    AddOptionRecompile(command);
                }
            }

            public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
            {
            }

            public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
            {
                if (ShouldIntercept(command, interceptionContext))
                {
                    AddOptionRecompile(command);
                }
            }

            public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
            {
            }

            private void AddOptionRecompile(IDbCommand command)
            {
                if (!command.CommandText.EndsWith(QueryHintText))
                {
                    command.CommandText += QueryHintText;
                }
            }

            private bool ShouldIntercept(IDbCommand command, DbCommandInterceptionContext interceptionContext)
            {
                return
                    command.CommandType == CommandType.Text &&
                    command is SqlCommand &&
                    interceptionContext.DbContexts.Any(interceptionDbContext => ReferenceEquals(interceptionDbContext, dbContext));
            }
        }
    }

看来订单有问题。我刚刚在 OptionRecompileScope 构造函数中重新添加了它,现在输出是正确的。

public OptionRecompileScope(DbContext context, ILogger logger)
        {
            interceptor = new OptionRecompileDbCommandInterceptor(context);
            DbInterception.Add(interceptor);
            if (Config.Debugging.LogDatabase)
            {
                context.Database.Log = q => logger.Debug(q);
            }
        }