一、概述
Entity Framework Core (EF Core)包含一些用于生成日志,响应事件和获取诊断结果的机制。其中每种机制都针对不同情况进行了定制,务必针对手头上的任务选择最佳机制,即使是多个机制都适用也是如此。本文将介绍EF日志每种机制,及其描述每种机制应用场景。
二、EF日志分类
下表提供了有关此处所述机制之间的差异的快速参考。 Microsoft.Extensions.Logging通常通过依赖项注入在每个应用程序中进行配置。但在EF级别,可使用不同的记录器配置没个上下文。
三、简单的日志记录
Entity Framework Core
简单日志记录可用于在开发和调试应用程序时轻松获取日志。这种形式的日志记录只需进行极少的配置,不需要额外的NuGet
包。
3.1 配置
可以在配置DbContext实例时使用LogTo
从任意类型的应用程序访问EF Core日志。此配置通常通过替代DbContext.OnConfiguring
来完成。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.LogTo(Console.WriteLine);
或者,可将LogTo作为AddDbContext的一部分来调用,或者在创建DbContextOptions实例以传递给DbContext构造函数时进行调用。
当使用 AddDbContext 或将 DbContextOptions 实例传递给 DbContext 构造函数时,仍会调用 OnConfiguring。 这使得它成为应用上下文配置的理想位置,而无需考虑如何构造 DbContext。
3.2 日志记录到控制台
ogTo
需要一个接受字符串Action
委托。EF Core将使用字符串为生成的每条日志消息调用此委托。然后由该委托对给定消息执行某些操作。
此委托通常使用Console.WriteLine
方式,如上所示。这导致每条日志消息都被写入控制台。
3.3 记录到凋试窗口
Debug.WriteLine
可用于将输出发送到Visual Studio
或其他IDE中凋试窗口。在这种情况下必须使用Lambda
语法,因此Debug
类是从发布版本编译的。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.LogTo(message => Debug.WriteLine(message));
3.4 记录到文件
写入文件时,需要为文件创建SteamWriter
或相似的类。然后可以像上面的其他示例一样使用WriteLine
方法。请记住,通过在释放上下文时是否编写器来确保文件完全关闭。示例:
private readonly StreamWriter _logStream=new StreamWriter("mylog.txt",append:true); protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder) { optionBuilder.LogTo(_logStream.WriteLine); } public override void Dispose() { base.Dispose(); _logStream.Dispose(); } public override async ValueTask DisposeAsync() { await base.DisposeAsync(); await _logStream.DisposeAsync(); }
3.5 敏感数据处理
默认情况下,EF Core不会在异常消息中包含任何数据的值。这是因为这些数据可能是机密数据,如果不处理异常,可能会在生产使用中泄露这些数据。
但是,了解数据值(尤其是键值)在凋试时非常有用。可以通过调用EnableSensitiveDataLogging()在EF Core中启用此功能。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.LogTo(Console.WriteLine) .EnableSensitiveDataLogging(); }
3.6 详细查询异常
出于性能原因,EF Core不会在try-catch块中包装每个调用以数据库提供程序读取值。但是,这有时会导致难以诊断的异常,尤其是当数据库在模型下允许的情况下返回NULL时。
启用EnableDetailedErrors
将导致EF引入这些try-catch块,从而提供更详细的错误。例如:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.LogTo(Console.WriteLine).EnableDetailedErrors(); }
3.6 日志级别
系统会为每条EF Core
日志消息分配由LogLevel
枚举定义的级别。默认情况下,EF Core简单日志记录包括Debug
级别或高级版的每条消息。LogTo
可以传递一个更高的最低级别来筛选掉某些消息。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
3.7 消息内容和格式设置
LogTo
中的默认内容跨多行设置格式。 第一行包含消息元数据:
LogLevel
作为四字符前缀- 本地时间戳,针对当前域性设置格式
EventId
,采用可以复制/粘贴以从CoreEventId
或其他EventId
类之一获取成员的格式,外加原始ID值。- 事件类别