在 EF Core 中使用 Microsoft.Extensions.Logging

Microsoft.Extensions.Logging 是一種可延伸的記錄機制,其中包含許多常見記錄系統的外掛程式提供者。 Microsoft 提供的外掛程式(例如 Microsoft.Extensions.Logging.Console )和協力廠商外掛程式(例如 Serilog.Extensions.Logging )都以 NuGet 套件的形式提供。

Entity Framework Core (EF Core) 與 完全整合 Microsoft.Extensions.Logging 。 不過,請考慮使用 簡單的記錄 來記錄,特別是針對不使用相依性插入的應用程式。

ASP.NET Core 應用程式

Microsoft.Extensions.Logging預設會在 ASP.NET Core 應用程式中 使用。 呼叫 AddDbContextAddDbContextPool 讓 EF Core 自動使用透過一般 ASP.NET 機制設定的記錄設定。

其他應用程式類型

其他應用程式類型可以使用 GenericHost 來取得與 ASP.NET Core 中使用的相同相依性插入模式。 AddDbContextAddDbContextPool 接著可以使用,就像在 ASP.NET Core 應用程式中一樣。

Microsoft.Extensions.Logging 也可以用於不使用相依性插入的應用程式,雖然 簡單的記錄 可以更容易設定。

Microsoft.Extensions.Logging 需要建立 LoggerFactory 。 此處理站應該儲存為某個位置的靜態/全域實例,並在每次建立 DbCoNtext 時使用。 例如,通常會將記錄器處理站儲存為 DbCoNtext 上的靜態屬性。

public static readonly ILoggerFactory MyLoggerFactory
    = LoggerFactory.Create(builder => { builder.AddConsole(); });

接著,這個單一/全域實例應該在 上 DbContextOptionsBuilder 向 EF Core 註冊。 例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLoggerFactory(MyLoggerFactory)
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");

取得詳細訊息

提示

使用 AddDbCoNtext 或 DbCoNtextOptions 實例傳遞至 DbCoNtext 建構函式時,仍會呼叫 OnConfiguring。 不論 DbCoNtext 的建構方式為何,這都適合套用內容組態。

敏感性資料

根據預設,EF Core 不會在例外狀況訊息中包含任何資料的值。 這是因為這類資料可能是機密資料,而且如果未處理例外狀況,可能會顯示在生產環境中。

不過,瞭解資料值,尤其是索引鍵,在偵錯時可能會很有説明。 這可以在 EF Core 中藉由呼叫 EnableSensitiveDataLogging() 來啟用。 例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.EnableSensitiveDataLogging();

詳細的查詢例外狀況

基於效能考慮,EF Core 不會包裝每個呼叫,以從 try-catch 區塊中的資料庫提供者讀取值。 不過,這有時會導致難以診斷的例外狀況,特別是當模型不允許資料庫傳回 Null 時。

開啟 EnableDetailedErrors 會導致 EF 引進這些 try-catch 區塊,進而提供更詳細的錯誤。 例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.EnableDetailedErrors();

特定訊息的設定

EF Core ConfigureWarnings API 可讓應用程式變更遇到特定事件時會發生什麼事。 這可以用來:

  • 變更記錄檔層級,以記錄事件
  • 完全略過記錄事件
  • 事件發生時擲回例外狀況

變更事件的記錄層級

有時候變更事件的預先定義記錄層級可能很有用。 例如,這可用來將兩個額外的事件從 LogLevel.Debug 升級為 LogLevel.Information

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(
            b => b.Log(
                (RelationalEventId.ConnectionOpened, LogLevel.Information),
                (RelationalEventId.ConnectionClosed, LogLevel.Information)));

隱藏記錄事件

同樣地,個別事件可以從記錄中隱藏。 這特別適合忽略已檢閱和瞭解的警告。 例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning));

擲回事件

最後,EF Core 可以設定為針對指定的事件擲回。 這特別適用于將警告變更為錯誤。 (事實上,這是方法的原始 ConfigureWarnings 目的,因此是名稱。例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Throw(RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning));

篩選和其他設定

如需記錄篩選和其他設定的指引,請參閱 在 .NET 中記錄。

EF Core 記錄事件定義于下列其中一個:

  • CoreEventId 適用于所有 EF Core 資料庫提供者通用的事件
  • RelationalEventId 適用于所有關系資料庫提供者通用的事件
  • 與目前資料庫提供者特定的事件類似的類別。 例如, SqlServerEventId 針對 SQL Server 提供者。

這些定義包含每個事件的事件識別碼、記錄層級和類別,如 所 Microsoft.Extensions.Logging 使用。