You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EF Core自定义内部服务中使用内置日志器?

解决EF Core自定义类型映射源的日志输出问题

问题根源

你手动从IServiceProvider获取IDiagnosticsLogger的方式无法关联到OnConfiguring中配置的LoggerFactory,因为EF Core的服务初始化顺序导致此时诊断日志器尚未绑定正确的日志提供者。正确的做法是通过构造函数直接注入EF框架管理的诊断日志器。

解决方案

1. 修正自定义类型映射源的构造函数

直接注入IDiagnosticsLogger<T>(使用EF的日志分类,比如DbLoggerCategory.Infrastructure),而非手动从服务容器获取。这样日志器会自动关联你配置的Debug和Console提供者,输出格式与EF原生日志一致。

public class CustomSqlServerTypeMappingSource : SqlServerTypeMappingSource
{
    private readonly IDiagnosticsLogger<DbLoggerCategory.Infrastructure> _diagnosticsLogger;

    // 注入基类依赖 + EF诊断日志器
    public CustomSqlServerTypeMappingSource(
        TypeMappingSourceDependencies dependencies,
        RelationalTypeMappingSourceDependencies relationalDependencies,
        IDiagnosticsLogger<DbLoggerCategory.Infrastructure> diagnosticsLogger)
        : base(dependencies, relationalDependencies)
    {
        _diagnosticsLogger = diagnosticsLogger;

        // 输出初始化日志,格式与EF原生一致
        _diagnosticsLogger.Logger.LogInformation(
            new EventId(10404, "CustomTypeMappingSourceInitialized"),
            "已创建自定义SqlServer类型映射源");
    }

    // 示例:自定义类型映射逻辑 + 日志输出
    protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo)
    {
        _diagnosticsLogger.Logger.LogDebug(
            new EventId(10405, "CustomTypeMappingLookup"),
            "正在查找类型映射:{MappingInfo}", mappingInfo);
            
        // 你的自定义映射逻辑
        var mapping = base.FindMapping(mappingInfo);
        if (mapping == null)
        {
            _diagnosticsLogger.Logger.LogWarning(
                new EventId(10406, "CustomTypeMappingNotFound"),
                "未找到类型映射:{MappingInfo}", mappingInfo);
        }

        return mapping;
    }
}

2. 确认DbContext配置顺序(可选)

确保UseLoggerFactory在服务替换前配置(EF Core配置顺序不强制,但提前配置日志能确保所有服务都使用同一日志提供者):

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    base.OnConfiguring(optionsBuilder);

    // 先配置日志工厂
    ILoggerFactory loggerFactory = LoggerFactory.Create(logging => 
        logging.AddDebug()
               .AddConsole()
               .SetMinimumLevel(LogLevel.Trace));
    optionsBuilder.UseLoggerFactory(loggerFactory);

    // 替换类型映射源服务
    optionsBuilder.ReplaceService<IRelationalTypeMappingSource, CustomSqlServerTypeMappingSource>();

    optionsBuilder.EnableSensitiveDataLogging();
    optionsBuilder.UseSqlServer("Server=...");
}

输出效果

运行后会输出与EF原生日志格式完全一致的内容:

info: Microsoft.EntityFrameworkCore.Infrastructure[10404]
      已创建自定义SqlServer类型映射源
dbug: Microsoft.EntityFrameworkCore.Infrastructure[10405]
      正在查找类型映射:Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingInfo

内容的提问来源于stack exchange,提问作者Jossean Yamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:43:14