首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在SQL Server Management Studio中执行NHibernate生成的预准备语句

在SQL Server Management Studio中执行NHibernate生成的预准备语句
EN

Stack Overflow用户
提问于 2012-06-13 20:39:14
回答 2查看 1.6K关注 0票数 3

配置NHibernate以显示执行的SQL做了它应该做的事情,但是无论何时需要将SQL字符串复制粘贴到SQL Server Management Studio中,我们都必须重新安排它以保持兼容性。

在我开始开发我自己的应用程序之前,我想重申这是以前没有做过的事情--我不想花时间在这上面等一下才知道。

有没有一种既便宜又实用的方法将NH生成的预准备语句转换为可立即执行的语句?

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-13 22:45:37

我知道你可以用nhibernate profiler做到这一点,但这不是一个免费的工具。我也会对做这件事的一个免费替代方案感兴趣。

http://nhprof.com/

编辑

看起来有一个针对log4net的自定义附加器,它会格式化它,这样您就可以实际运行NHibernate输出。我在下面列出的博客中看到了它:

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

下面是我从上面的博客中摘取的代码,并对其进行了修改以使用Guid:

代码语言:javascript
运行
复制
/// <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();
    }
}

下面是如何将此输出发送到控制台的方法:

代码语言:javascript
运行
复制
<appender name="NHibernateSqlAppender" type="NHibernatePlayground.Custom.NHibernateSqlAppender, NHibernatePlayground">
    <appender-ref ref="console" />
</appender>

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

注意:

这似乎会在生产系统中导致一些相当严重的性能问题。我还没有找到更好的方法来做这件事,但是对于任何使用这个工具的人来说,要当心这些性能问题

票数 7
EN

Stack Overflow用户

发布于 2012-06-14 19:59:55

我已经有一段时间没有使用它了,但我相信使用拦截器将符合您的标准。

代码语言:javascript
运行
复制
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 here所有。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11015005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档