C#如何配置Entity Framework日志_C# EF Core SQL日志输出方法【实用】
在EFCore开发阶段,可通过LogTo方法输出SQL日志。需设置LogLevel.Information以显示所有语句,启用EnableSensitiveDataLogging可获取真实参数值,但仅限开发环境。写入文件时需注意AutoFlush和线程安全。该方法适合快速调试,生产环境建议使用Microsoft.Extensions.Logging。
要在开发阶段快速查看EF Core生成的SQL语句,LogTo可能是最直接、最轻量的方式。不需要额外引入Microsoft.Extensions.Logging或者第三方日志库,一行配置就能看到查询的全貌——包括语句本身、参数值以及执行耗时。
具体用法很简单,在自定义DbContext的OnConfiguring方法里这样写就行:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.LogTo(Console.WriteLine);
这么一来,每次执行查询或者保存操作,SQL语句、参数和执行时间就会直接打印到控制台。不过有一点需要注意:在Windows Forms或者IIS这类托管环境中,Console.WriteLine可能不显示。这时候可以换成Debug.WriteLine,日志会输出到Visual Studio调试模式的“输出”窗口。如果是在Linux容器里部署,Console.WriteLine仍然能用,日志会进入stdout流,通过docker logs也能捕获到。
还有一个细节容易被忽略:默认情况下,LogTo只记录Warning及以上级别的日志,也就是说只会输出慢查询或者异常信息。如果想看到所有SQL,必须显式启用LogLevel.Information。
如何让LogTo显示完整的参数和SQL
EF Core默认会对敏感数据(比如密码字段)做脱敏处理,参数值通常以占位符形式出现,类似@__id_0这种。想看到真实的参数值,需要启用EnableSensitiveDataLogging:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){ optionsBuilder .LogTo(Console.WriteLine, LogLevel.Information) .EnableSensitiveDataLogging();}
这里有几个关键点值得说清楚:
LogLevel.Information是必须的,只有这个级别才能捕获普通查询的SQL和参数;如果只用Warning,只能看到慢查询或异常。EnableSensitiveDataLogging需要在LogTo之后调用才会生效,顺序是敏感的。- 这个选项只适合开发环境。生产环境一旦开启,明文密码、身份证号这些信息就会直接被打到日志里,后果可想而知。
把日志写入文件而不是控制台
LogTo接收的是任意Action委托,所以转向文件也很容易实现:
var logFile = new StreamWriter("ef-logs.txt", append: true) { AutoFlush = true };protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.LogTo(logFile.WriteLine);
不过这里有几个坑需要提前避开:
- 千万别忘了设置
AutoFlush = true,否则日志可能一直滞留在缓冲区里不落盘。 - 多线程并发写入同一个文件时,
StreamWriter不是线程安全的,容易丢日志或者乱序。如果你想在真正的高并发场景下用,可以考虑ConcurrentQueue配合后台轮询写入,或者直接用ILogger配合FileLoggerProvider。 - 对于长期运行的服务,日志滚动(按大小或日期切分)几乎是必备功能,但
LogTo本身不提供这个能力,得自己封装一套机制。
为什么不再用EF6风格的Database.Log
如果你是从EF6迁移过来的老手,可能会下意识地尝试context.Database.Log = Console.WriteLine,但EF Core已经彻底移除了Database类型的Log属性。所有日志配置都必须通过DbContextOptionsBuilder在构建上下文之前完成。如果你试图在运行时动态开关日志(比如某个请求开启、某个请求关闭),LogTo是做不到的。这时候得上IDbCommandInterceptor或者ILogger才行。
说实话,LogTo最适合的场景就是开发阶段快速调试。一旦涉及环境区分、分级日志、结构化字段、对接ELK或Sentry这些真正生产级的需求,它就只是一个临时拐杖了——不提供日志上下文(比如请求ID),不支持异步写入,也不兼容现有日志生态。这些重活,还是交给Microsoft.Extensions.Logging更稳妥。


































