12-3. 資料庫連接日誌問題你想為每次與資料庫的連接和斷開記錄日誌解決方案EF為DbContext的連接公開了一個StateChange 事件.我們需要處理這個事件, 為每次與資料庫的連接和斷開記錄日誌.假設我們的模型如Figure 12-3所示. 在 Listing 12-3代碼里, 我們創建一...
12-3. 資料庫連接日誌
問題
你想為每次與資料庫的連接和斷開記錄日誌
解決方案
EF為DbContext的連接公開了一個StateChange 事件.我們需要處理這個事件, 為每次與資料庫的連接和斷開記錄日誌.
假設我們的模型如Figure 12-3所示. 在 Listing 12-3代碼里, 我們創建一些Donation 實例,然後把它們保存到資料庫. 這裡的代碼實現override SaveChanges() 方法為我們的StateChange 事件提供切入點.
Figure 12-3. The model with the Donation entity
Listing 12-3. Code to Implement Logging of Open and Close of a Database Connection
class Program
{
static void Main(string[] args)
{
RunExample();
}
static void RunExample()
{
using (var context = new EFRecipesEntities())
{
context.Donations.Add(new Donation
{
DonorName = "Robert Byrd",
Amount = 350M
});
context.Donations.Add(new Donation
{
DonorName = "Nancy McVoid",
Amount = 250M
});
context.Donations.Add(new Donation
{
DonorName = "Kim Kerns",
Amount = 750M
});
Console.WriteLine("About to SaveChanges()");
context.SaveChanges();
}
using (var context = new EFRecipesEntities())
{
var list = context.Donations.Where(o => o.Amount > 300M);
Console.WriteLine("Donations over $300");
foreach (var donor in list)
{
Console.WriteLine("{0} gave {1}", donor.DonorName,
donor.Amount.ToString("C"));
}
}
Console.WriteLine("Press any key to close...");
Console.ReadLine();
}
}
public partial class EFRecipesEntities
{
public override int SaveChanges()
{
this.Database.Connection.StateChange += (s, e) =>
{
var conn = (DbConnection)s;
Console.WriteLine("{0}: Database: {1}, State: {2}, was: {3}",
DateTime.Now.ToShortTimeString(), conn.Database,
e.CurrentState, e.OriginalState);
};
return base.SaveChanges();
}
}
上述Listing 12-3代碼輸出如下:
About to SaveChanges()
09:56 : Database: EFRecipes, State: Open, was: Closed
09:56: Database: EFRecipes, State: Closed, was: Open
Donations over $300
Robert Byrd gave $350.00
Kim Kerns gave $750.00
原理
我們實現override SaveChanges() 方法,為我們的StateChange事件提供切入點,該事件處理程式接收兩個參數:事件的發送者(sender)和StateChangeEventArgs.第二個參數提供了訪問連接的當前狀態和原始狀態, 我們為這兩個與資料庫相關的狀態做日誌記錄.如果你特點註意日誌內容的順序,你會註意到在第二個using塊里,與資料庫的連接在foreach執行要查詢時重新啟動,而不是在寫查詢語句時. 這個演示說明瞭一個重要的概念:查詢只在必要時才進行.在我們的例子中,查詢在遍歷期間才執行