我有带 DI 的 .NET 7 控制台应用程序,想用 Serilog 将查询记录到数据库。所以我创建了我的 Serilog 记录器并将其添加到 DI:
var logger = new LoggerConfiguration().ReadFrom.Configuration(config).CreateLogger();
services.AddSingleton<ILogger>(logger)
但是如何配置
AppDbContext
才能将查询写入我的日志?
您需要将 ILoggerFactory 连接到
DbContextOptionsBuilder.UseLoggerFactory(ILoggerFactory) 方法
下面的完整示例。
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Logging.Extensions;
using Microsoft.Extensions.Hosting;
namespace MyCompany.MyProductLine.MyAppName.DomainDataLayer.EntityFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class MyAppNameDbContext : DbContext
{
public const string ErrorMessageILoggerFactoryIsNull = "ILoggerFactory is null";
public const string ErrorMessageIHostEnvironmentIsNull = "IHostEnvironment is null";
private readonly IHostEnvironment hostEnvironment; /* https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostenvironment?view=dotnet-plat-ext-7.0&viewFallbackFrom=net-6.0 */
private readonly ILoggerFactory loggerFactory; /* https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory?view=dotnet-plat-ext-7.0&viewFallbackFrom=net-6.0 */
public MyAppNameDbContext(
ILoggerFactory loggerFactory,
IHostEnvironment hostEnvironment,
DbContextOptions<MyAppNameDbContext> options)
: base(options)
{
this.loggerFactory = loggerFactory ??
throw new ArgumentNullException(
ErrorMessageILoggerFactoryIsNull,
(Exception)null);
this.hostEnvironment = hostEnvironment ?? throw new ArgumentNullException(
ErrorMessageIHostEnvironmentIsNull,
(Exception)null);
/* note, the base-class checks for null for the DbContextOptions-"options" */
if (this.hostEnvironment.IsDevelopment())
{
this.Database.EnsureCreated(); /* you do not need this, this is included as an example to a full working example */
}
}
public DbSet<DepartmentEntity> Departments { get; set; } /* you do not need this, this is included as an example to a full working example */
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new DepartmentMap()); /* you do not need this, this is included as an example to a full working example */
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
// Allow null if you are using an IDesignTimeDbContextFactory
if ((this.loggerFactory != null
&& Debugger.IsAttached
&& (this.hostEnvironment.IsDevelopment()))
)
{
//// Probably shouldn't log sql statements in production, so use "flags" (above if conditions) to only do it when a developer is involved.
optionsBuilder.UseLoggerFactory(this.loggerFactory);
}
}
}
边注:
在外面并与上面的“接线”分开......为了确保你有 Serilog(或任何“具体”记录器)正常工作...... 您应该输入一些“.LogTrace”、“.LogDebug”、“LogInfo”调用....
Aka,确保你的那些工作......在连接 EF 记录器之前......只是为了确保“基础”工作......在认为 EF 连接不起作用之前。 (#hindSightAdviceOnMyPart)