LINQ to Entitiesをやってて思うこと。
どんなSQLが発行されてるのか見たい!せめてSELECT文だけでも…。
というときのやりかたです。(LINQ to SQLだとLogプロパティにConsole.Outとか代入するだけで見れました。ただ、この方法だと全部出ちゃう。)
LINQ to EneitiesのクエリはObjectQueryになるので、そいつのToTraceStringメソッドを呼び出してやると、SQLが取れるみたいです。
“みたい”というのはToTraceStringメソッドが「データ ソースに対して実行するコマンドを返します。」という説明文がMSDNに書いてあって、恐らくこの場合DBがデータソースだからSQLだろうという事です。
ということで、以下のようなメソッドを作っておくと吉。
[Conditional("DEBUG")]
private static void TraceQuery<T>(IQueryable<T> query)
{
var objectQuery = query as ObjectQuery;
if (objectQuery == null)
{
Console.WriteLine("SQLに変換できません");
return;
}
Console.WriteLine(objectQuery.ToTraceString());
var parameters = objectQuery.Parameters;
if (parameters.Count != 0)
{
Console.WriteLine("Parameters: ");
foreach (var param in parameters)
{
Console.WriteLine("{0}: {1}", param.Name, param.Value);
}
}
}
これは、標準出力に出力してるけど、ちゃんとデバッグ用のログに出力するなりlog4netとか使うなりして、それなりのところに出力してやればOKだと思う。
ちなみに以下のようなコードを書くと
using (var ctx = new EduEntities())
{
int i = 1;
var query = from emp in ctx.Employees
where emp.ID == i
select emp;
TraceQuery(query);
}
次のような結果が表示されます。
SELECT
1 AS [C1],
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[Salary] AS [Salary],
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [dbo].[Employees] AS [Extent1]
WHERE [Extent1].[ID] = @p__linq__1
Parameters:
p__linq__1: 1
機械的に名前がつけられているので読みにくいですが、ばっちり表示されてます!