繼續上篇:EntityFramework和EntityFramework.Extended使用說明——性能,語法和產生的sql 1.監控sql 上篇中的sql監控採用的是 Microsoft SQL Server Management Studio中工具->profiler去監控的.當然,Expre ...
繼續上篇:EntityFramework和EntityFramework.Extended使用說明——性能,語法和產生的sql
1.監控sql
上篇中的sql監控採用的是 Microsoft SQL Server Management Studio中工具->profiler去監控的.
當然,Express版本是沒有此功能的.
如果您使用不了profiler或者覺得不方便,那麼,給出監控sql的第二方案.
找到的資料是英文的,還好,容易理解.
原文鏈接:https://blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/
a.控制台列印
var db = new PhoneBookEntities();//以後的db都是指它 db.Database.Log = Console.Write;//列印sql語句 db.Database.ExecuteSqlCommand("update GroupInfo set GroupName='hello' where GroupId=220");//此語句不用db.SaveChanges();一樣生效
監控結果:
已於 2016/6/21 星期二 10:30:23 +08:00 打開了連接已於 2016/6/21 星期二 10:30:23 +08:00 啟動了事務update GroupInfo set GroupName='hi' where GroupId=220 -- 正在 2016/6/21 星期二 10:30:23 +08:00 執行-- 已在 1 毫秒內完成,結果為: 1 已於 2016/6/21 星期二 10:30:23 +08:00 提交了事務已於 2016/6/21 星期二 10:30:23 +08:00 關閉了連接
b.記錄sql到文件
如果控制台列印不能滿足您的需求,也可以記錄到文件里.
方法:
var db = new PhoneBookEntities(); db.Database.Log = s => LogHelper.Write(s);//調用LogHelper類的方法 db.Database.ExecuteSqlCommand("update GroupInfo set GroupName='hello' where GroupId=220");//此語句不用db.SaveChanges();一樣生效
LogHelper.cs
public class LogHelper { public static void Write(string str) { var path = Path.Combine(new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.FullName, "logs.txt"); string errmsg = string.Format("{0}", str); System.IO.File.AppendAllText(path, errmsg); } }
就是這麼簡單!
2.EF中的事務
上面例子看到產生的sql監控記錄,
db.Database.ExecuteSqlCommand("update GroupInfo set GroupName='hello' where GroupId=220");
此語句執行啟動了事務.
測試研究一下怎麼回事.
以下兩句:
db.Database.ExecuteSqlCommand("update GroupInfo set GroupName='hi' where GroupId=209");
db.Database.ExecuteSqlCommand("update GroupInfo set GroupName='hello' where GroupId=220");
經監控,分別啟動並提交了兩次事務.(如果sql命令為insert,delete也是同樣道理)
怎麼把這兩個sql語句放到一個事務里呢?別急,最後再說明.
先看看最熟悉的db.SaveChanges()語句:以下語句本身沒有實際意義,為了測試而寫.
var gi = db.GroupInfo.FirstOrDefault(c => c.GroupName.Contains("g1!")); var ci = db.ContactInfo.FirstOrDefault(c => c.ID == 12); ci.ContactName += "!"; gi.GroupName += "!"; db.SaveChanges(); ci.ContactName += "!"; gi.GroupName += "!"; db.SaveChanges();
監控產生的sql:
已於 2016/6/21 星期二 11:06:52 +08:00 打開了連接SELECT TOP (1) [Extent1].[GroupId] AS [GroupId], [Extent1].[GroupName] AS [GroupName] FROM [dbo].[GroupInfo] AS [Extent1] WHERE [Extent1].[GroupName] LIKE N'%g1!%' -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 1 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:06:52 +08:00 關閉了連接已於 2016/6/21 星期二 11:06:52 +08:00 打開了連接SELECT TOP (1) [Extent1].[ID] AS [ID], [Extent1].[ContactId] AS [ContactId], [Extent1].[IsDelete] AS [IsDelete], [Extent1].[Account] AS [Account], [Extent1].[ContactName] AS [ContactName], [Extent1].[CommonMobile] AS [CommonMobile], [Extent1].[HeadPortrait] AS [HeadPortrait], [Extent1].[AttFile] AS [AttFile], [Extent1].[GroupId] AS [GroupId] FROM [dbo].[ContactInfo] AS [Extent1] WHERE 12 = [Extent1].[ID] -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 1 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:06:52 +08:00 關閉了連接已於 2016/6/21 星期二 11:06:52 +08:00 打開了連接已於 2016/6/21 星期二 11:06:52 +08:00 啟動了事務UPDATE [dbo].[ContactInfo] SET [ContactName] = @0 WHERE ([ID] = @1) -- @0: '李四1!!!!!!!' (Type = String, Size = 50) -- @1: '12' (Type = Int32) -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 1 毫秒內完成,結果為: 1 UPDATE [dbo].[GroupInfo] SET [GroupName] = @0 WHERE ([GroupId] = @1) -- @0: 'g1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' (Type = String, Size = 300) -- @1: '216' (Type = Int32) -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 0 毫秒內完成,結果為: 1 已於 2016/6/21 星期二 11:06:52 +08:00 提交了事務已於 2016/6/21 星期二 11:06:52 +08:00 關閉了連接已於 2016/6/21 星期二 11:06:52 +08:00 打開了連接已於 2016/6/21 星期二 11:06:52 +08:00 啟動了事務UPDATE [dbo].[ContactInfo] SET [ContactName] = @0 WHERE ([ID] = @1) -- @0: '李四1!!!!!!!!' (Type = String, Size = 50) -- @1: '12' (Type = Int32) -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 0 毫秒內完成,結果為: 1 UPDATE [dbo].[GroupInfo] SET [GroupName] = @0 WHERE ([GroupId] = @1) -- @0: 'g1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' (Type = String, Size = 300) -- @1: '216' (Type = Int32) -- 正在 2016/6/21 星期二 11:06:52 +08:00 執行-- 已在 0 毫秒內完成,結果為: 1 已於 2016/6/21 星期二 11:06:52 +08:00 提交了事務已於 2016/6/21 星期二 11:06:52 +08:00 關閉了連接監控記錄
每次db.SaveChanges()會預設開啟事務,執行sql語句,提交事務.多看看,好好理解一下.
如何把兩個db.SaveChanges()放到一個事務里呢?
寫法:
var gi = db.GroupInfo.FirstOrDefault(c => c.GroupName.Contains("g1!")); var ci = db.ContactInfo.FirstOrDefault(c => c.ID == 12); using (var tx = db.Database.BeginTransaction()) { try { ci.ContactName += "!"; gi.GroupName += "!"; //db.SaveChanges();//這個語句影響到事務中sql的數量,有此語句事務里4條sql,沒有就是2條.對於此案例,不影響結果. ci.ContactName += "!"; gi.GroupName += "!"; db.SaveChanges();//必須要有 tx.Commit();//此語句不要漏了,否則監控結果會是釋放了事務,而不是提交了事務! } catch (Exception) { tx.Rollback(); } }
監控產生的sql:
[沒有第一個db.SaveChanges()]
已於 2016/6/21 星期二 11:20:49 +08:00 打開了連接SELECT TOP (1) [Extent1].[GroupId] AS [GroupId], [Extent1].[GroupName] AS [GroupName] FROM [dbo].[GroupInfo] AS [Extent1] WHERE [Extent1].[GroupName] LIKE N'%g1!%' -- 正在 2016/6/21 星期二 11:20:49 +08:00 執行-- 已在 0 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:20:49 +08:00 關閉了連接已於 2016/6/21 星期二 11:20:49 +08:00 打開了連接SELECT TOP (1) [Extent1].[ID] AS [ID], [Extent1].[ContactId] AS [ContactId], [Extent1].[IsDelete] AS [IsDelete], [Extent1].[Account] AS [Account], [Extent1].[ContactName] AS [ContactName], [Extent1].[CommonMobile] AS [CommonMobile], [Extent1].[HeadPortrait] AS [HeadPortrait], [Extent1].[AttFile] AS [AttFile], [Extent1].[GroupId] AS [GroupId] FROM [dbo].[ContactInfo] AS [Extent1] WHERE 12 = [Extent1].[ID] -- 正在 2016/6/21 星期二 11:20:49 +08:00 執行-- 已在 0 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:20:49 +08:00 關閉了連接已於 2016/6/21 星期二 11:20:49 +08:00 打開了連接已於 2016/6/21 星期二 11:20:49 +08:00 啟動了事務UPDATE [dbo].[ContactInfo] SET [ContactName] = @0 WHERE ([ID] = @1) -- @0: '李四1!!' (Type = String, Size = 50) -- @1: '12' (Type = Int32) -- 正在 2016/6/21 星期二 11:20:49 +08:00 執行-- 已在 1 毫秒內完成,結果為: 1 UPDATE [dbo].[GroupInfo] SET [GroupName] = @0 WHERE ([GroupId] = @1) -- @0: 'g1!!!' (Type = String, Size = 300) -- @1: '222' (Type = Int32) -- 正在 2016/6/21 星期二 11:20:49 +08:00 執行-- 已在 0 毫秒內完成,結果為: 1 已於 2016/6/21 星期二 11:20:49 +08:00 提交了事務已於 2016/6/21 星期二 11:20:49 +08:00 關閉了連接監控記錄
[有第一個db.SaveChanges()]
已於 2016/6/21 星期二 11:21:49 +08:00 打開了連接SELECT TOP (1) [Extent1].[GroupId] AS [GroupId], [Extent1].[GroupName] AS [GroupName] FROM [dbo].[GroupInfo] AS [Extent1] WHERE [Extent1].[GroupName] LIKE N'%g1!%' -- 正在 2016/6/21 星期二 11:21:49 +08:00 執行-- 已在 1 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:21:49 +08:00 關閉了連接已於 2016/6/21 星期二 11:21:49 +08:00 打開了連接SELECT TOP (1) [Extent1].[ID] AS [ID], [Extent1].[ContactId] AS [ContactId], [Extent1].[IsDelete] AS [IsDelete], [Extent1].[Account] AS [Account], [Extent1].[ContactName] AS [ContactName], [Extent1].[CommonMobile] AS [CommonMobile], [Extent1].[HeadPortrait] AS [HeadPortrait], [Extent1].[AttFile] AS [AttFile], [Extent1].[GroupId] AS [GroupId] FROM [dbo].[ContactInfo] AS [Extent1] WHERE 12 = [Extent1].[ID] -- 正在 2016/6/21 星期二 11:21:49 +08:00 執行-- 已在 0 毫秒內完成,結果為: SqlDataReader 已於 2016/6/21 星期二 11:21:49 +08:00 關閉了連接已於 2016/6/21 星期二 11:21:49 +08:00 打開了連接已於 2016/6/21 星期二 11:21:49 +08:00 啟動了事務UPDATE [dbo].[ContactInfo] SET [ContactName] = @0 WHERE ([ID] = @1) -- @0: '李四1!' (Type = String, Size = 50) -- @1: '12' (Type = Int32) -- 正在 2016/6/21 星期二 11:21:49 +08:00 執行-- 已在 1 毫秒內完成,結果為: 1 UPDATE [dbo].[GroupInfo] SET [GroupName] = @0 WHERE ([GroupId] = @1) -- @0: 'g1!!' (Type = String, Size = 300) -- @1: '222' (Type = Int32) -- 正在 2016/6/21 星期二 11:21:49 +08:00 執行-- 已在 1 毫秒內完成,結果為: 1 UPDATE [dbo].[ContactInfo] SET [ContactName] = @0 WHERE ([ID] = @1) -- @0: '李四1!!' (Type = String, Size = 50) -- @1: '12' (Type = Int32) -- 正在 2016/6/21 星期二 11:21:49 +08:00 執行-- 已在 0 毫秒內完成,結果為: 1 UPDATE [dbo].[GroupInfo] SET [GroupName] = @0 WHERE ([GroupId] = @1) -- @0: 'g1!!!' (Type = String, Size = 300) --