Sql Serverクエリビジュアライザーに示されているように、以前はcontext.Logを使用してLINQからSQLで生成されたSQLステートメントをトレースしていました–生成されたSQLクエリが表示されません
context.Log = new OutputWindowWriter();
EFの場合、上記のアプローチのような簡単なものはありますか?
Sql Serverクエリビジュアライザーに示されているように、以前はcontext.Logを使用してLINQからSQLで生成されたSQLステートメントをトレースしていました–生成されたSQLクエリが表示されません
context.Log = new OutputWindowWriter();
EFの場合、上記のアプローチのような簡単なものはありますか?
一般に、組み込みのトレーサーまたは任意のロガーを簡単に接続できます
context.Database.Log = msg => Trace.WriteLine(msg);
DbContextコンストラクターで。詳細については、MSDNを参照してください。MSからの他のいくつかのアプローチがここにあります(すべてDataContext.Logプロパティに基づいています)。
Nateが言及したクラッチソリューションについて言えば、EF v6では機能しません(このバグレポートを参照してください)。
参考文献
Clutch.Diagnostics.EntityFramework(NuGetで利用可能)は私にとって完全に機能し、EFTracingProviderよりも単純です。
EF 6の更新:
Entity Framework 6以降、Entity Frameworkがデータベースにコマンドを送信するときはいつでも、このコマンドはアプリケーションコードによって傍受される可能性があります。これはSQLのログ記録に最も一般的に使用されますが、コマンドを変更または中止するためにも使用できます。
具体的には、EFには次のものが含まれます。
* LINQtoSQLのDataContext.Logに類似したコンテキストのLogプロパティ。
*ログに送信される出力の内容とフォーマットをカスタマイズするメカニズム。
*より優れた制御/柔軟性を提供する傍受用の低レベルのビルディングブロック。
EFトレースプロバイダーは、トレースとして実行されたすべてのSQLステートメントを出力できます。必要に応じて、これを使用して独自のログを追加することもできます。コンテキストクラスのコンストラクターに配置できるコードを次に示します(これはDBContext用ですが、ObjectContextを使用するための微調整はかなり明白です)。
// enable logging all queries executed by EF
var cx = ((IObjectContextAdapter)this).ObjectContext; // change to var cx = this; if using ObjectContext.
cx.EnableTracing();
cx.Connection.GetTracingConnections().ToList().ForEach(
c =>
{
c.CommandExecuting += (s, e) => Log(e);
c.CommandFailed += (s, e) => Log(e);
c.CommandFinished += (s, e) => Log(e);
});
これに対する多くの解決策がありますが、コードで最も単純なのは、LINQステートメントのIQueryableでToString()を呼び出すことです。
var query = db.Employees.Where(x => x.ID = 1); //query will be an IQueryable object
var sql = query.ToString();
これはEF4.1以降のみです(以前はObjectQueryでToTraceStringを呼び出すことがこれを実現する方法でした)。
EF6に対するNateの回答を拡張すると、データベース操作のログ記録とインターセプトNLogCommandInterceptor
に見られるように、CommandTextのみが表示されます。
そのcommandTextが失敗する原因となった特定のパラメーター値があった場合、パラメーター値はログに出力されません。私の場合、外部キー違反の原因となっている値をログに記録したいと思いました。
これは、このようにNLogCommandInterceptorのLogIfError
メソッドを変更することで改善できます。
private void LogIfError<TResult>(DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
{
if (interceptionContext.Exception != null)
{
var commandDumper = new DbCommandDumper(command);
Log.Warn(Command failed:\r\n{0}", commandDumper.GetLogDump());
// Exception will get logged further up the stack
}
}
ここで、DbCommandDumperクラスはDbCommandをTSQLに再構築し、テストデータベースで再生できます。
お持ちのObjectQueryインスタンスのToTraceStringメソッドを使用できると思います。もう1つのアプローチは、プロジェクトから出て行くSQLをログに記録するVisualStudionのIntelliTraceを調べることです。