我们在使用EF Core的时候,很多时候需要在Visual Studio的输出窗口中知道EF Core在后台生成的SQL语句是什么,这个需求可以通过自定义EF Core的ILoggerFactory和ILogger类来实现:
首先定义一个实现了ILogger接口的类EFLogger,主要目的是将EF Core生成的Log信息输出到Visual Studio的输出窗口:
然后定义一个实现了ILoggerFactory接口的类EFLoggerFactory,用于创建上面定义的EFLogger类的实例:
using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace Model { class EFLogger : ILogger { protected string categoryName; public EFLogger(string categoryName) { this.categoryName = categoryName; } public IDisposable BeginScope<TState>(TState state) { return null; } public bool IsEnabled(LogLevel logLevel) { return true; } public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { if (logLevel != LogLevel.Information) { return; } //通过Debugger.Log方法来将EF Core生成的Log信息输出到Visual Studio的输出窗口 Debugger.Log(0, categoryName, "=============================== EF Core log started ===============================\r\n"); Debugger.Log(0, categoryName, formatter(state, exception) + "\r\n"); Debugger.Log(0, categoryName, "=============================== EF Core log finished ===============================\r\n"); } } public class EFLoggerFactory : ILoggerFactory { public void AddProvider(ILoggerProvider provider) { } public ILogger CreateLogger(string categoryName) { return new EFLogger(categoryName);//创建EFLogger类的实例 } public void Dispose() { } } }
最后在DbContext的OnConfiguring方法中,调用optionsBuilder.UseLoggerFactory来将EFLoggerFactory类的实例注入给EF Core,这样所有DbContext的Log信息,都会由EFLogger类输出到Visual Studio的输出窗口了。
特别要注意的是: static readonly EFLoggerFactory loggerFactory = new EFLoggerFactory(); 这里一定要用静态类
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //配置数据库连接地址--测试库 if (string.IsNullOrWhiteSpace(SomConfig.OMSConfig)) { string str = System.Environment.CurrentDirectory; FileStream file = new FileStream(str + "\\Config.json", FileMode.Open); byte[] byData = new byte[(int)file.Length];//构建一个缓冲池 file.Seek(0, SeekOrigin.Begin); file.Read(byData, 0, (int)file.Length); var HaveRead = System.Text.Encoding.UTF8.GetString(byData).Substring(1); var array = JArray.Parse(HaveRead)[0]; SomConfig.DataBase = array.Value<string>("DataBase"); SomConfig.DataBaseConfig(); SomConfig.Port = array.Value<string>("Port"); file.Close(); } if (!optionsBuilder.IsConfigured) { optionsBuilder.UseLoggerFactory(loggerFactory); } optionsBuilder.UseSqlServer(SomConfig.OMSConfig); }