web-dev-qa-db-ja.com

Dapperを使用してSQLをトレース/ログする方法はありますか?

生成されたSQLをデバッグログなどにダンプする方法はありますか?私はwinformsソリューションでそれを使用しているので、ミニプロファイラのアイデアは私にはうまくいきません。

35

同じ問題が発生し、検索を実行した後、すぐに使用できるものがないコードを実装しました。 nugetにパッケージがあります MiniProfiler.Integrations 共有したいと思います。

V2の更新:他のデータベースサーバーとの連携をサポートします。MySQLの場合、 MiniProfiler.Integrations.MySql が必要です。

以下は、SQL Serverを使用する手順です。

1.接続のインスタンス化

var factory = new SqlServerDbConnectionFactory(_connectionString);
using (var connection = DbConnectionFactoryHelper.New(factory, CustomDbProfiler.Current))
{
 // your code
}

2.すべての作業が完了したら、必要に応じてすべてのコマンドをファイルに書き込みます

File.WriteAllText("SqlScripts.txt", CustomDbProfiler.Current.ProfilerContext.BuildCommands());
23
hazjack

現在、Dapperにはインストルメンテーションポイントがありません。ご存知のように、これはおそらく(著者として)ミニプロファイラーを使用してこれを処理しているためです。しかし、それが役立つ場合、ミニプロファイラのコア部分は実際にはアーキテクチャに中立になるように設計されており、winforms、wpf、wcfなどでそれを使用している他の人を知っています-これによりプロファイリング/トレース接続ラッパーにアクセスできます。

理論的には、包括的なキャプチャポイントを追加することは完全に可能ですが、私は2つのことを心配しています。

  • (主に)セキュリティ:dapperにはコンテキストの概念がないため、本当に本当に悪性コードが静かにすべてを嗅ぎ付けるのは簡単ですdapperを経由するSQLトラフィック。私はその音が本当に好きではありません(これは、発信者が接続を所有するため、「装飾」アプローチの問題ではないため、ロギングコンテキストです)
  • (二次)パフォーマンス:しかし...実際には、単純なデリゲートチェック(ほとんどの場合nullと思われる)が大きな影響を与えると言うのは難しい

もちろん、他にできることは、ミニプロファイラーから接続ラッパーコードを盗み、プロファイラーコンテキストを次のように置き換えるだけです:Debug.WriteLineなど.

11
Marc Gravell

この質問にまだ多くのヒットがあるので、ここに更新を追加するだけです-最近では Glimpse または Stackify Prefix を使用します。どちらもsqlコマンドトレース機能を備えています。

元の質問をしたときに探していたものではありませんが、同じ問題を解決します。

2

これは完全なものではなく、本質的に少しのハックですが、SQLがあり、パラメーターを初期化する場合は、基本的なデバッグに役立ちます。

public static class DapperExtensions
    {
        public static string ArgsAsSql(this DynamicParameters args)
        {
            var sb = new StringBuilder();
            foreach (var name in args.ParameterNames)
            {
                var pValue = args.Get<dynamic>(name);

                var type = pValue.GetType();

                if (type == typeof(DateTime))
                    sb.AppendFormat("DECLARE @{0} DATETIME ='{1}'\n", name, pValue.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                else if (type == typeof(bool))
                    sb.AppendFormat("DECLARE @{0} BIT = {1}\n", name, (bool)pValue ? 1 : 0);
                else if (type == typeof(int))
                    sb.AppendFormat("DECLARE @{0} INT = {1}\n", name, pValue);
                else if (type == typeof(List<int>))
                    sb.AppendFormat("-- REPLACE @{0} IN SQL: ({1})\n", name, string.Join(",", (List<int>)pValue));
                else
                    sb.AppendFormat("DECLARE @{0} NVARCHAR(MAX) = '{1}'\n", name, pValue.ToString());
            }

            return sb.ToString();
        }
    }

次に、これを即時ウィンドウまたはウォッチウィンドウで使用して、SQLを取得できます。

2
MrEdmundo