【EF Core】如何輸出日誌到Visual Studio的輸出窗口

我們在使用EF Core的時候,很多時候需要在Visual Studio的輸出窗口中知道EF Core在後臺生成的SQL語句是什麼,這個需求可以通過自定義EF Core的ILoggerFactory和ILogger類來實現:

首先定義一個實現了ILogger接口的類EFLogger,主要目的是將EF Core生成的Log信息輸出到Visual Studio的輸出窗口:

using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;

namespace WebCore.Utils
{
    public 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)
        {
            //通過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");
        }
    }
}

然後定義一個實現了ILoggerFactory接口的類EFLoggerFactory,用於創建上面定義的EFLogger類的實例:

using Microsoft.Extensions.Logging;

namespace WebCore.Utils
{
    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的輸出窗口了。

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using WebCore.Utils;

namespace WebCore.Entities
{
    public partial class TestDBContext : DbContext
    {
        public TestDBContext()
        {
            this.Database.SetCommandTimeout(0);//設置SqlCommand永不超時
        }

        public TestDBContext(DbContextOptions<TestDBContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Person> Person { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseLoggerFactory(new EFLoggerFactory());//將EFLoggerFactory類的實例注入給EF Core,這樣所有DbContext的Log信息,都會由EFLogger類輸出到Visual Studio的輸出窗口了
                optionsBuilder.UseSqlServer("Server=localhost;User Id=sa;Password=1qaz!QAZ;Database=TestDB");
            }
        }
        
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //省略代碼...
        }
    }
}

注意OnConfiguring這個方法是virtual的,所以我們也可以選擇在DbContext的子類中來重寫這個方法,在子類的OnConfiguring中注入EFLoggerFactory類的實例到DbContext。

 

最後我們來看看EF Core日誌輸出的效果,還是很規整的,最重要的是我們可以實時的得到EF Core在後臺生成的SQL語句:

 

發佈了189 篇原創文章 · 獲贊 153 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章