簡體   English   中英

在SQL Server Management Studio中執行NHibernate生成的預准備語句

[英]Execute NHibernate-generated prepared statements in SQL Server Management Studio

配置NHibernate以顯示已執行的SQL可以實現預期,但每當需要將SQL字符串復制粘貼到SQL Server Management Studio時,我們必須重新排列它以便兼容。

在我開始開發我自己的應用程序之前,將其解析並重新排列為更適合管理工作室的SQL之前,我想重申以前沒有這樣做過 - 我不想花時間在這上面找出來。

是否有一種廉價且切實可行的方法將NH生成的預處理語句轉換為可立即執行的語句?

提前致謝

我知道你可以用nhibernate profiler做到這一點,但這不是一個免費的工具。 我也有興趣免費替代這樣做。

http://nhprof.com/

編輯

看起來有一個自定義的appender用於log4net,它將格式化它,這樣你就可以實際運行sql NHibernate spits了。 我在下面列出的博客中看到了它:

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

下面是我從上面的博客中獲取的代碼,並修改為與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();
    }
}

以下是將此輸出發送到控制台的方法:

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

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

注意:

這似乎會在生產系統中引起一些相當重要的性能問題。 我還沒有找到更好的方法來做到這一點,但對於任何使用它的人都要注意這些性能問題

我有一段時間沒有使用它,但我相信使用攔截器符合你的標准。

using NHibernate;
using System.Diagnostics;

public class SqlStatementInterceptor : EmptyInterceptor
{
    public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
    {
        Trace.WriteLine(sql.ToString());
        return sql;
    }
}

信用轉到用戶mindplay.dk 這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM