如何设置 DbContext 以将错误记录到 ILogger?

How do I set up a DbContext to log errors to ILogger?

我有一个 ASP.NET 核心应用程序,在我的 Startup.cs 文件中,在 ConfigureServices(IServiceCollection services) 函数中,我试图编写如下内容:

//...

namespace MyNamespace
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            //...

            services.AddDbContext<ModelDbContext>(options =>
            {
                options.UseSqlServer(_configuration.GetConnectionString("Model"),
                    sqlServerOptionsAction => sqlServerOptionsAction.EnableRetryOnFailure());
                options.LogTo(
                    filter: (eventId, _) => eventId.Id == CoreEventId.ExecutionStrategyRetrying,
                    logger: (eventData) =>
                    {
                        var retryEventData = (ExecutionStrategyEventData)eventData;
                        var exceptions = retryEventData.ExceptionsEncountered;
                        var exception = exceptions[exceptions.Count - 1];
                        logger.LogWarning(exception,
                            "Database error occurred. Retry #{ExceptionsCount} with delay {RetryEventDataDelay} due to error: {ExceptionMessage}",
                            exceptions.Count, retryEventData.Delay, exception.Message);
                    });
            }, ServiceLifetime.Transient);

            //...
        }

        //...
    }
}

但是,我不知道如何使上面的这一行起作用:

logger.LogWarning(exception,
    "Database error occurred. Retry #{ExceptionsCount} with delay {RetryEventDataDelay} due to error: {ExceptionMessage}",
    exceptions.Count, retryEventData.Delay, exception.Message);

问题是我没有对 ILogger 实例的引用,所以我不知道如何在该上下文中调用 LogWarning 函数。

所以我的问题是:

您可以使用 the other overload 的 AddDbContext,它提供应用程序的 IServiceProvider,您可以从中获取记录器,但不知何故,这种重载被记录为不太受欢迎。

另一种方法是通过构造函数将 ILogger 注入到您的 DbContext 中,然后配置您的登录 DbContext.OnConfiguring 以登录到注入的记录器。

“问题是我没有对 ILogger 的实例的引用”让我从这里开始。您可以使用 ILogger<TCategoryName> Interface,用于启用使用依赖注入激活命名 ILogger。

将您的构造函数更改为此。

private readonly ILogger _logger;

public Startup(IConfiguration configuration)
{
    Configuration = configuration;

    using var loggerFactory = LoggerFactory.Create(builder =>
    {
        builder.SetMinimumLevel(LogLevel.Warning);
        builder.AddConsole();
        builder.AddEventSourceLogger();
    });
    _logger = loggerFactory.CreateLogger<Startup>();
}

现在您可以在 Startup

的任何地方使用它
public void ConfigureServices(IServiceCollection services)
{
    _logger.LogWarning("something");
    // ..
}