是否可以分别切换读取和写入的日志(log)记录?
Use this in only Development Environment个
我会这样做:
使用DbCommandInterceptor类拦截执行的SQL语句.
因此,首先我创建一个继承DbCommandInterceptor
的类QueryCommandInterceptor
:
public class QueryCommandInterceptor : DbCommandInterceptor
{
private readonly ILogger<QueryCommandInterceptor> _logger;
public QueryCommandInterceptor(ILogger<QueryCommandInterceptor> logger)
{
_logger = logger;
}
}
添加该方法以判断该命令是否为写操作,即DELETE
、UPDATE
、INSERT
,如果是,还记录该命令:
private void LogCommand(DbCommand command)
{
if (command.CommandText.Contains("INSERT") ||
command.CommandText.Contains("UPDATE") ||
command.CommandText.Contains("DELETE"))
{
_logger.LogInformation($"Executing SQL command: {command.CommandText}");
}
}
DbCommandInterceptor
中的最后QueryCommandInterceptor
个重写方法:
using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Data.Common;
namespace StackOverflow
{
public class QueryCommandInterceptor : DbCommandInterceptor
{
private readonly ILogger<QueryCommandInterceptor> _logger;
public QueryCommandInterceptor(ILogger<QueryCommandInterceptor> logger)
{
_logger = logger;
}
public override InterceptionResult<int> NonQueryExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<int> result)
{
LogCommand(command);
return result;
}
public override ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
LogCommand(command);
return new ValueTask<InterceptionResult<int>>(result);
}
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result)
{
LogCommand(command);
return result;
}
public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result,
CancellationToken cancellationToken = default)
{
LogCommand(command);
return new ValueTask<InterceptionResult<DbDataReader>>(result);
}
public override InterceptionResult<object> ScalarExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<object> result)
{
LogCommand(command);
return result;
}
public override ValueTask<InterceptionResult<object>> ScalarExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<object> result,
CancellationToken cancellationToken = default)
{
LogCommand(command);
return new ValueTask<InterceptionResult<object>>(result);
}
private void LogCommand(DbCommand command)
{
if (command.CommandText.Contains("INSERT") ||
command.CommandText.Contains("UPDATE") ||
command.CommandText.Contains("DELETE"))
{
_logger.LogInformation($"Executing SQL command: {command.CommandText}");
}
}
}
}
最后,在我的Program.cs
中连接我的记录器,也添加了新的拦截器:
builder.Logging.ClearProviders();
var logger = LoggerFactory.Create(builder =>
{
builder.AddConsole();
}).CreateLogger<QueryCommandInterceptor>();
builder.Services.AddDbContext<StackContext>(options =>
{
options.UseSqlServer(connectionString);
options.AddInterceptors(new QueryCommandInterceptor(logger));
}
);