前面的Part 1-3的文章,介紹了Entity Data Model、Entity SQL、ObjectQuery、EntityCommand、LINQ to Entities等等及其代碼示範。這篇文章主要示範如何通過相關技術或Debug工具,如SQL Server Profiler、ToTraceString 方法、eSqlBlast 工具、LINQPad工具等等,來查看產生的T-SQL指令碼。
本系列文章前面部分連結:
Entity Data Model (EDM) 深入分析, Part 1
Entity Data Model (EDM) 深入分析, Part 2
Entity Data Model (EDM) 深入分析, Part 3
Entity Data Model 是一個概念性模型,所有Entity SQL和LINQ to Entities 查詢將最終轉化為T-SQL的指令碼,從資料庫中查詢資料。這裡示範了幾種方法來查看產生的T-SQL,有助於Debug或分析問題。
1. 使用SQL Server Profiler 工具
與LINQ to SQL比較而言,ObjectContext 類沒有提供Log屬性或者通用的log機制,因此,無法在Visual Studio 中跟蹤所有的T-SQL語句。
如果你想查看所有執行的T-SQL語句,你需要使用SQL Server的Profiler 工具,關於具體如何使用SQL Server Profiler工具,請參考如下文章:
SQL Profiler: Features, functions and setup in SQL Server 2005
http://blog.entlib.com/EntLib/archive/2008/10/27/sql-profiler-features-functions-and-setup-in-sql-server-2005.aspx
2. ToTraceString 方法
另外一種方法去查看產生的T-SQL語句的方法,包括 EntityCommand和ObjectQuery類都有一個ToTraceString() 方法。在一些情況下,可以用來查看內部到底產生什麼SQL指令碼,而不必一定要使用SQL Server Profiler 工具。需要注意的是:ToTraceString() 方法實際上沒有執行查詢操作,僅僅是轉化查詢為SQL指令碼。
通過增加一個斷點,你可以輕鬆查看SQL指令碼,需要記住的是:事先需要開啟資料庫連接,否則會拋出InvalidOperationException 異常(Execution of the command requires an open and available connection. The connection’s current state is closed.)
(1)Entity SQL : EntityCommand.ToTraceString() 樣本指令碼
public IList<Category> GetParentCategory()
{
IList<Category> result = null;
EntityDataReader rdr;
EntityCommand cmd;
string esqlQuery;
using (EntityConnection conn = new EntityConnection("name=AdventureWorksLTEntities"))
{
conn.Open();
esqlQuery = @"Select VALUE c from AdventureWorksLTEntities.Category AS c
Where c.ParentCategory is null ";
result = new List<Category>();
cmd = conn.CreateCommand();
cmd.CommandText = esqlQuery;
Console.WriteLine(cmd.CommandText);
Console.WriteLine(cmd.ToTraceString());
rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (rdr.Read())
{
result.Add(this.productGateway.MaterializeCategory(rdr));
}
conn.Close();
}
return result;
}
樣本介面如下:
(2)Entity SQL : ObjectQuery.ToTraceString() 樣本指令碼如下:
NorthwindEntities context = new NorthwindEntities();
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +
"WHERE emp.Country = @country";
var query = context.CreateQuery<Employee>(sql);
query.Parameters.Add(new ObjectParameter("country", "USA"));
if (context.Connection.State != ConnectionState.Open)
context.Connection.Open();
Console.WriteLine(query.ToTraceString());
(3)LINQ to Entities : (query as ObjectQuery).ToTraceString() 樣本指令碼
需要使用類型轉換,將LINQ to Entities (IQueryable) 查詢轉化為ObjectQuery,這樣就可以調用ToTraceString() 方法了。
NorthwindEntities context = new NorthwindEntities();
string country = "USA";
var query = from e in context.Employees
where e.Country == country
select e;
if (context.Connection.State != ConnectionState.Open)
context.Connection.Open();
Console.WriteLine((query as ObjectQuery<Employee>).ToTraceString());
也可以通過反射(Reflection)和Invoke() 方法,得到相同的結果:
Console.WriteLine(query.GetType().GetMethod("ToTraceString").Invoke(query, null));
3. 使用eSqlBlast 工具
微軟也提供了一個免費的工具來協助學習Entity SQL。
eSqlBlast 的(含有原始碼,需要自己編譯一下)及其相關介紹(eSqlBlast for VS 2008 SP1):
http://code.msdn.microsoft.com/esql/Release/ProjectReleases.aspx?ReleaseId=991
如果懶得編譯,可以直接在本文章底部點擊下載連結,下載已經編譯好的可執行檔。
運行介面如下:
Connection 頁面用來指定3個中繼資料檔案(CSDL/SSDL/MSL)和資料庫連接字串。資料庫連接字串可以直接從App.config 複製過來。點擊Connect 按鈕進行串連。
Model 頁面用來顯示所有的EntitySets和EntityTypes。
Query 頁面可以輸入 Entity SQL指令碼,你會注意到eSqlBlast 支援智能提示(IntelliSense),酷吧!!!目前,Visual Studio 2008 sp1 尚不支援Entity SQL 的職能提示呢。
點擊Execute 執行按鈕,執行結果將以HTML的格式顯示在Results 頁面,如所示。包括4個部分:Enttiy Command (也就是CommandText 屬性值)、Store Command(產生的T-SQL指令碼,也就是ToTraceString() 方法產生的指令碼)、Record Count(結果集的記錄數)、Data(實際記錄結果)。
4. 使用免費LINQPad 工具
LINQPad 是一個優秀的LINQ 運算式測試載入器,原本設計用來執行LINQ to Objects 和LINQ to SQL查詢,但是也可以用來執行LINQ to Entities 查詢。
如所示,執行LINQ to SQL查詢,並調用擴充方法Dump() 輸出結果。
LINQPad 免費工具可以到如下地址下載:
http://www.linqpad.net/