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);
}
}
我将下面的代码成功附加到从 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);
}
}