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/
本文配套源碼