web-dev-qa-db-fra.com

Existe-t-il un moyen de suivre \ log le sql en utilisant Dapper?

Existe-t-il un moyen de vider le sql généré dans le journal de débogage ou quelque chose? Je l'utilise dans une solution Winforms, donc l'idée du mini-profileur ne fonctionnera pas pour moi.

35
Mladen Mihajlovic

J'ai eu le même problème et j'ai implémenté du code après avoir effectué une recherche, mais sans aucun élément prêt à l'emploi. Il y a un paquet sur nuget MiniProfiler.Integrations Je voudrais partager.

Mise à jour V2 : il prend en charge de travailler avec d'autres serveurs de base de données, pour MySQL il nécessite d'avoir MiniProfiler.Integrations.MySql

Voici les étapes pour travailler avec SQL Server:

1.Instancier la connexion

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

2.Après avoir terminé tous les travaux, écrivez toutes les commandes dans un fichier si vous le souhaitez

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

Dapper n'a actuellement pas de point d'instrumentation ici. Cela est peut-être dû, comme vous le constatez, au fait que nous (en tant qu'auteurs) utilisons un mini-profileur pour gérer cela. Cependant, si cela aide, les parties centrales du mini-profileur sont en fait conçues pour être neutres en architecture, et je connais d'autres personnes l'utilisant avec winforms, wpf, wcf, etc. - qui vous donneraient accès à l'encapsuleur de connexion de profilage/traçage .

En théorie, il serait parfaitement possible d'ajouter un point de capture de couverture, mais je suis préoccupé par deux choses:

  • (principalement) la sécurité: puisque dapper n'a pas de concept de contexte, il serait vraiment vraiment facile pour un code malveillant de s'attacher tranquillement pour renifler tout le trafic sql qui passe par dapper; Je n'aime vraiment pas le son de cela (ce n'est pas un problème avec l'approche "décorateur", car l'appelant possède la connexion, d'où le contexte de journalisation)
  • performances (secondaires): mais ... en vérité, il est difficile de dire qu'une simple vérification de délégué (qui serait vraisemblablement null dans la plupart des cas) aurait beaucoup d'impact

Bien sûr, l'autre chose que vous pourriez faire est de voler le code du wrapper de connexion du mini-profileur et de remplacer le contenu du profileur par juste: Debug.WriteLine etc.

11
Marc Gravell

Juste pour ajouter une mise à jour ici car je vois que cette question reçoit encore pas mal de hits - ces jours-ci, j'utilise soit Aperç ou Stackify Prefix qui ont tous deux des capacités de trace de commande sql.

Ce n'est pas exactement ce que je cherchais quand j'ai posé la question d'origine mais résoudre le même problème.

2
Mladen Mihajlovic

Ce n'est pas exhaustif et c'est essentiellement un peu de hack, mais si vous avez votre sql et que vous souhaitez initialiser vos paramètres, c'est utile pour le débogage de base.

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();
        }
    }

Vous pouvez ensuite simplement l'utiliser dans les fenêtres immédiates ou de surveillance pour saisir le SQL.

2
MrEdmundo