Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Eseguire istruzioni preparate generate da NHibernate in SQL Server Management Studio

So che puoi farlo con nhibernate profiler ma questo non è uno strumento gratuito. Sarei anche interessato a un'alternativa gratuita per farlo.

http://nhprof.com/

Modifica

Sembra che ci sia un appender personalizzato là fuori per log4net che lo formatterà in modo tale da poter effettivamente eseguire gli sputi sql NHibernate. L'ho visto nel blog elencato di seguito:

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

Di seguito è riportato il codice che ho preso dal blog sopra e modificato per funzionare con Guid:

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

Ecco come inviare questo output alla console:

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

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

NOTA:

Sembra che ciò causi alcuni problemi di prestazioni abbastanza significativi in ​​un sistema di produzione. Non ho ancora trovato un modo migliore per farlo, ma per chiunque lo utilizzi, fai attenzione a questi problemi di prestazioni