觀察 EF Core 產生的 SQL 指令

微信扫一扫,分享到朋友圈

觀察 EF Core 產生的 SQL 指令

如果你跟我一樣,過去在專案裡都是自己連資料庫寫 SQL 指令,轉用 EF Core 之後,免不了會想確認 Where().Select() 產生的 SQL 查詢是否有效率,好奇 SaveChanges() 背後 EF Core 是怎麼更新資料庫?

要解答上述疑惑,最好的方法莫過於啟用 Logging 功能,直接觀察 EF Core 產生的每一條 SQL 指令。做法很簡單,Startup.ConfigureServices() AddDbContextPool() 時呼叫 .UseLoggerFactory(),傳入 ILoggerFactory,若要將結果輸出到 Console,可使用 LoggerFactory.Create(builder => builder.AddConsole()) 建立將結果顯示在 Console 的 ILoggerFactory 物件:

public void ConfigureServices(IServiceCollection services)
{
//註冊 DB Context,指定使用 SQL 資料庫
services.AddDbContextPool<JournalDbContext>(options =>
{
//TODO: 實際應用時,連線字串不該寫死在程式碼裡,應應移入設定檔並加密儲存
options.UseSqlServer(Configuration.GetConnectionString("LocalDB"))
//啟用 Logging 觀察 SQL 指令
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
});
services.AddRazorPages();
}

也可以指定同時輸出到多個管道,例如 Console 跟 Debug.WriteLine():

options.UseSqlServer(Configuration.GetConnectionString("LocalDB"))
//啟用 Logging 觀察 SQL 指令
.UseLoggerFactory(LoggerFactory.Create(builder =>
{
builder.AddConsole().AddDebug();
}));

這樣,我們就能觀察到 LINQ 查詢跟 SaveChanges() 所對應的 SQL 指令,印證 EF Core 更新衝突處理策略 文章裡提到的: 1) EF Core 會追蹤屬性狀態,只更新有異動的欄位 2) RowVersion 欄位會被當成 WHERE 條件,用以偵測資料是否被他人異動。

不過預設 Log 只會看到 SQL 指令,不包含參數內容,如果要連參數一起顯示,在 UseLoggerFactory() 後方加上 EnableSensitiveDataLogging():

options.UseSqlServer(Configuration.GetConnectionString("LocalDB"))
//啟用 Logging 觀察 SQL 指令
.UseLoggerFactory(LoggerFactory.Create(builder =>
{
builder.AddConsole().AddDebug();
}))
.EnableSensitiveDataLogging();

啟用後,輸出結果將包含參數內容:

但請務必注意,顯示參數功能偏向偵錯抓蟲的非常手段(所以預設是關閉的),在線上環境不應常態啟用。參數內容可能包含客戶個資、信用卡號等機敏資料,當心別讓 Log 變成資料外洩的來源,

Tips of how to enable EF Core logging to monitor SQL statement and parameters.

微信扫一扫,分享到朋友圈

觀察 EF Core 產生的 SQL 指令

vuePress操作指南

上一篇

微信小程序点击跳转传值

下一篇

你也可能喜欢

觀察 EF Core 產生的 SQL 指令

长按储存图像,分享给朋友