91

このスレッドによると、生成されたSQLvia をログに記録できますEFが、どうDbContext.SaveChanges()ですか? 追加のフレームワークなしでこの仕事をする簡単な方法はありますか?

4

8 に答える 8

141

エンティティ フレームワーク 6.0 では、Database クラスにプロパティがありますAction<string> Log。そのため、ロギングの設定は次のように簡単です。

context.Database.Log = Console.WriteLine;

より高度なニーズについては、インターセプターをセットアップできます。

于 2013-12-24T09:03:42.760 に答える
15

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());
    }
于 2013-08-19T17:04:49.640 に答える
2

You can use SQL Server Profiler and run it against the database server you are connecting to.

于 2013-06-02T16:32:13.970 に答える
1

これは役立つはずです、EFTracingProvider

http://code.msdn.microsoft.com/EFProviderWrappers

于 2013-06-02T18:13:31.507 に答える