如何在EF Core 3中启用日志记录?

17
我正在使用Entity Framework Core 3预览版5和ASP.NET Core 3预览版5。在Visual Studio 2019的调试输出窗口中,我没有从EF Core获得任何日志。我阅读了文档,但是之后我更加困惑:
1.根据https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-2.1,日志记录应该自动设置:

使用“AddDbContext”方法之一时,不需要调用此方法。“AddDbContext”将确保EF使用的ILoggerFactory从应用程序服务提供程序获取。

然而我的经验并非如此。
2.我尝试通过将ILoggerFactory注入到ConfigureServices来启用日志记录(我打算将其传递给DbContextOptionsBuilder.UseLoggerFactory,但这不再可能,参见https://github.com/aspnet/Announcements/issues/353) 那么,我该如何在EF Core 3.0中设置日志记录以输出到调试窗口?谢谢!

想了解一下关于投票关闭的情况。能否请您解释一下并提供一个解决方案,谢谢。 - stefan.at.kotlin
请问您是否已经查看了此链接:https://learn.microsoft.com/en-us/ef/core/miscellaneous/logging - TanvirArjel
1
关闭投票的原因是你没有发布任何能够重现问题的代码。任何人都不知道你是否根本没有启用日志记录,或者仅记录信息消息。有一些类似这样的问题如此,询问如何关闭日志记录。默认的日志记录配置会写入控制台、调试输出和事件日志。 - Panagiotis Kanavos
1
好的,我明白了。同时我也找到了原因:EF Core 3.0中有一个重大变化。现在只有在调试模式下才会显示SQL查询。我应该更仔细地检查是否有来自EF Core的输出。我一直走错了方向。提到的重大变化:https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#query-execution-is-logged-at-debug-level 还可以参考 https://stackoverflow.com/questions/55997906/net-core-3-0-consoleloggerfactory-for-sqlite?rq=1 - stefan.at.kotlin
2
应注意此更改将再次被还原:https://github.com/aspnet/EntityFrameworkCore/issues/14523 - stefan.at.kotlin
2个回答

37
3.0 RTM及更高版本的更新:日志级别已恢复为信息。请查看文档中的过滤日志内容以获取更多详细信息。还可以参考appsettings.json中可用于过滤的类别列表
EF Core在Debug级别记录日志,但主机构建器使用的默认级别是Information。因此,必须手动将日志级别设置为Trace或Debug。
默认情况下,此代码不会记录任何EF事件。
static async Task Main(string[] args)
{
    var host = Host
        .CreateDefaultBuilder(args)             
        .ConfigureServices((context, services) =>
        {
            var configuration = context.Configuration;
            services.AddDbContext<MyContext>(options =>
                options.UseSqlServer(configuration.GetConnectionString("someConnection")));                    
        })                
        .Build();

    using (var ctx = host.Services.GetRequiredService<MyContext>())
    {
        var cnt = await ctx.Customers.CountAsync();
        Console.WriteLine(cnt);
    }            
}

只会记录这个事件:
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
  Entity Framework Core 3.0.0-preview6.19304.10 initialized 'ConsolidatorsContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None

要记录EF事件,我们需要通过appsettings.json或代码将EF Core事件的日志级别更改为TraceDebug。例如,在appsettings.json中包含以下内容:
    "Logging": {
        "LogLevel": {
            "Microsoft.EntityFrameworkCore":"Debug"
        }
    },

将记录EF事件:
  dbug: Microsoft.EntityFrameworkCore.Infrastructure[10401]
        An 'IServiceProvider' was created for internal use by Entity Framework.
  info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
        Entity Framework Core 3.0.0-preview6.19304.10 initialized 'MyContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
  dbug: Microsoft.EntityFrameworkCore.Database.Connection[20000]
        Opening connection to database 'Customers' on server '10.0.0.216'.
  dbug: Microsoft.EntityFrameworkCore.Database.Connection[20001]
        Opened connection to database 'Customers' on server '10.0.0.216'.
  dbug: Microsoft.EntityFrameworkCore.Database.Command[20100]
        Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
        SELECT COUNT(*)
        FROM [Customers] AS [c]
  dbug: Microsoft.EntityFrameworkCore.Database.Command[20101]
        Executed DbCommand (42ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
        SELECT COUNT(*)
        FROM [Customers] AS [c]
  4
  dbug: Microsoft.EntityFrameworkCore.Database.Command[20300]
        A data reader was disposed.
  dbug: Microsoft.EntityFrameworkCore.Database.Connection[20002]
        Closing connection to database 'Customers' on server '10.0.0.216'.
  dbug: Microsoft.EntityFrameworkCore.Database.Connection[20003]
        Closed connection to database 'Customers' on server '10.0.0.216'.
  dbug: Microsoft.EntityFrameworkCore.Infrastructure[10407]
        'MyContext' disposed.

谢谢!看起来我们同时回复了,不过请看一下我上面的评论。请注意,在未来的版本中,所需的日志记录级别将被改回信息级别:https://github.com/aspnet/EntityFrameworkCore/issues/14523 - stefan.at.kotlin
@stefan.at.wpf 正确的链接是 https://github.com/aspnet/EntityFrameworkCore/issues/15888 - Panagiotis Kanavos

4
出现日志记录不发生的另一个关键原因是:在AddDbContext()注释中有一个未提及的依赖项。

使用其中一种“AddDbContext”方法时,无需调用此方法。'AddDbContext'将确保EF使用的ILoggerFactory从应用程序服务提供程序获取。

只有当您的DbContextDbContextOptions<T>注入到base构造函数中时,它才能正常工作。
例如,从Scaffold-DbContext自动生成的构造函数。
public MyDbContext(DbContextOptions<MyDbContext> options) 
   : base(options)
{
}

那个被注入的对象已经配置了一个LoggerFactory,所以如果你不这样做,你将不得不在你的OnConfiguring()方法中手动设置日志记录器。


仍然无法使用AddDbContext<MyDbContext>();正常工作。 - Wouter
4
不知道如何回应这样一个含糊不清的、匆忙发表的评论。 - Granger
我试图从选项中获取日志记录器工厂,但它总是为 null。事实证明这并不是必需的,然后该注释实际上就有意义了。 - Wouter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接