Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Exécuter des instructions préparées générées par NHibernate dans SQL Server Management Studio

Je sais que vous pouvez le faire avec le profileur nhibernate mais ce n'est pas un outil gratuit. Je serais également intéressé par une alternative gratuite à cela.

http://nhprof.com/

Modifier

On dirait qu'il existe un appender personnalisé pour log4net qui le formatera de manière à ce que vous puissiez réellement exécuter le sql que NHibernate crache. Je l'ai vu dans le blog ci-dessous :

http://gedgei.wordpress.com/ 2011/09/03/logging-nhibernate-queries-with-parameters/

Vous trouverez ci-dessous le code que j'ai extrait du blog ci-dessus et que j'ai modifié pour fonctionner avec les Guids :

/// <summary>
/// This log4net appender is used for outputting NHibernate sql statements in a sql management studio friendly format.
/// This means you should be able to copy the sql output from this appender and run it directly.  Normally in the NHibernate
/// output there is parameterized sql that must be manually edited to run it.
/// </summary>
public class NHibernateSqlAppender : ForwardingAppender
{
    private const string GuidRegex = @"\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b";

    protected override void Append(LoggingEvent loggingEvent)
    {
        var loggingEventData = loggingEvent.GetLoggingEventData();

        if (loggingEventData.Message.Contains("@p"))
        {
            StringBuilder messageBuilder = new StringBuilder();

            string message = loggingEventData.Message;
            var queries = Regex.Split(message, @"command\s\d+:");

            foreach (var query in queries)
                messageBuilder.Append(ReplaceQueryParametersWithValues(query));

            loggingEventData.Message = messageBuilder.ToString();
        }

        base.Append(new LoggingEvent(loggingEventData));
    }

    public static string ReplaceQueryParametersWithValues(string query)
    {
        string returnQuery = Regex.Replace(query, @"@p\d+(?=[,);\s])(?!\s*=)", match =>
        {
            Regex parameterValueRegex = new Regex(string.Format(@".*{0}\s*=\s*(.*?)\s*[\[].*", match));
            return parameterValueRegex.Match(query).Groups[1].ToString();
        });

        //Place single quotes around all Guids in the sql string
        returnQuery = Regex.Replace(returnQuery, GuidRegex, "'$0'", RegexOptions.IgnoreCase);

        int parameterListIndex = returnQuery.LastIndexOf("@p0");

        if (parameterListIndex != -1)
        {
            //Truncate the paramter list off the end since we are substituting the actual values in the regular expression above
            //The -1 also cuts off the semicolon at the end
            return returnQuery.Substring(0, parameterListIndex).Trim();
        }

        return returnQuery.Trim();
    }
}

Voici comment envoyer cette sortie à la console :

<appender name="NHibernateSqlAppender" type="NHibernatePlayground.Custom.NHibernateSqlAppender, NHibernatePlayground">
    <appender-ref ref="console" />
</appender>

<root>
    <appender-ref ref="NHibernateSqlAppender" />
</root>

REMARQUE :

Il semble que cela cause des problèmes de performances assez importants dans un système de production. Je n'ai pas encore trouvé de meilleur moyen de le faire, mais pour tous ceux qui l'utilisent, méfiez-vous de ces problèmes de performances