このスレッドによると、生成されたSQL
via をログに記録できますEF
が、どうDbContext.SaveChanges()
ですか? 追加のフレームワークなしでこの仕事をする簡単な方法はありますか?
8 に答える
エンティティ フレームワーク 6.0 では、Database クラスにプロパティがありますAction<string> Log
。そのため、ロギングの設定は次のように簡単です。
context.Database.Log = Console.WriteLine;
より高度なニーズについては、インターセプターをセットアップできます。
http://www.codeproject.com/Articles/499902/Profiling-Entity-Framework-5-in-codeを参照してください。Code First、POCO DbContext、Entity Framework 5 を使用して、Cook 氏のアイデアを asp.net mvc アプリケーションに実装しました。
アプリケーションのコンテキスト クラスは、DbContext から派生します。
public class MyDbContext : DbContext
コンテキストのコンストラクターは、SavingChanges イベントをフックします (デバッグ ビルドの高価なリフレクションのみを実行したい)。
public MyDbContext(): base("MyDbContext")
{
#if DEBUG
((IObjectContextAdapter)this).ObjectContext.SavingChanges += new EventHandler(objContext_SavingChanges);
#endif
}
変更の保存イベントは、生成された sql を出力ウィンドウに書き込みます。クック氏からコピーしたコードは、DbParameter を SqlParamter に変換します。これは、Sql Server にアクセスしているためそのままにしておきますが、他の種類のデータベースにアクセスすると変換が失敗すると想定しています。
public void objContext_SavingChanges(object sender, EventArgs e)
{
var commandText = new StringBuilder();
var conn = sender.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.Name == "Connection")
.Select(p => p.GetValue(sender, null))
.SingleOrDefault();
var entityConn = (EntityConnection)conn;
var objStateManager = (ObjectStateManager)sender.GetType()
.GetProperty("ObjectStateManager", BindingFlags.Instance | BindingFlags.Public)
.GetValue(sender, null);
var workspace = entityConn.GetMetadataWorkspace();
var translatorT =
sender.GetType().Assembly.GetType("System.Data.Mapping.Update.Internal.UpdateTranslator");
var translator = Activator.CreateInstance(translatorT, BindingFlags.Instance |
BindingFlags.NonPublic, null, new object[] {objStateManager,workspace,
entityConn,entityConn.ConnectionTimeout }, CultureInfo.InvariantCulture);
var produceCommands = translator.GetType().GetMethod(
"ProduceCommands", BindingFlags.NonPublic | BindingFlags.Instance);
var commands = (IEnumerable<object>)produceCommands.Invoke(translator, null);
foreach (var cmd in commands)
{
var identifierValues = new Dictionary<int, object>();
var dcmd =
(DbCommand)cmd.GetType()
.GetMethod("CreateCommand", BindingFlags.Instance | BindingFlags.NonPublic)
.Invoke(cmd, new[] { translator, identifierValues });
foreach (DbParameter param in dcmd.Parameters)
{
var sqlParam = (SqlParameter)param;
commandText.AppendLine(String.Format("declare {0} {1} {2}",
sqlParam.ParameterName,
sqlParam.SqlDbType.ToString().ToLower(),
sqlParam.Size > 0 ? "(" + sqlParam.Size + ")" : ""));
commandText.AppendLine(String.Format("set {0} = '{1}'", sqlParam.ParameterName, sqlParam.SqlValue));
}
commandText.AppendLine();
commandText.AppendLine(dcmd.CommandText);
commandText.AppendLine("go");
commandText.AppendLine();
}
System.Diagnostics.Debug.Write(commandText.ToString());
}
You can use SQL Server Profiler and run it against the database server you are connecting to.
これは役立つはずです、EFTracingProvider