一、概述
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值。- 事件类别