如何在运行时在代码中获取NHibernate生成的SQL?

时间:2010-07-20 16:34:33

标签: .net sql nhibernate

我知道你可以通过将它连接到log4net或将它输出到控制台(“show_sql”选项)来查看NHibernate生成的SQL,但有没有办法在运行时获取代码中生成的SQL?

我希望能够做的是获取ICriteria对象(或IQuery)并将生成的SQL转储到屏幕或自定义日志(而不是log4net)。有点像...

var sql = criteria.GetGeneratedSql() // Wishful thinking

可以这样做吗?


编辑:感谢DanP找到了适合Java的"Hibernate Criteria to SQL Translation"类,我第一次尝试将其移植到NHibernate。似乎适用于简单的情况,但绝对可以使用一些改进(即错误处理等)

using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Impl;
using NHibernate.Loader;
using NHibernate.Loader.Criteria;
using NHibernate.Persister.Entity;

public class HibernateHqlAndCriteriaToSqlTranslator
{
    public HibernateHqlAndCriteriaToSqlTranslator() { }

    public ISessionFactory SessionFactory { get; set; }

    public string ToSql(ICriteria criteria)
    {
        var c = (CriteriaImpl) criteria;
        var s = (SessionImpl)c.Session;
        var factory = (ISessionFactoryImplementor)s.SessionFactory;
        String[] implementors = factory.GetImplementors(c.EntityOrClassName);
        var loader = new CriteriaLoader(
            (IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]),
            factory, 
            c, 
            implementors[0], 
            s.EnabledFilters);

        return ((OuterJoinLoader)loader).SqlString.ToString();
    }

    public string ToSql(string hqlQueryText)
    { 
        if (!String.IsNullOrEmpty(hqlQueryText))
        {
            var translatorFactory = new ASTQueryTranslatorFactory();
            var factory = (ISessionFactoryImplementor) this.SessionFactory;
            var translator = translatorFactory.CreateQueryTranslator(
                hqlQueryText, 
                hqlQueryText, 
                new Dictionary<String, IFilter>(), 
                factory);
            translator.Compile(new Dictionary<String, String>(), false);
            return translator.SQLString;
        }

        return null;
    }
}

3 个答案:

答案 0 :(得分:5)

这篇文章描述了如何从Hibernate中的hql或条件中获取底层sql;我想移植它以使用NHibernate不会太棘手:

http://narcanti.keyboardsamurais.de/hibernate-criteria-to-sql-translation.html

答案 1 :(得分:2)

使用NHibernate 3.2,这似乎可以从HQL查询中获取SQL:

private string GetSQL(string hql)
{
    using (var iSession = ...)
    {
        var session = (NHibernate.Engine.ISessionImplementor)iSession;
        var sf = (NHibernate.Engine.ISessionFactoryImplementor)iSession.SessionFactory;

        var sql = new NHibernate.Engine.Query.HQLStringQueryPlan(hql, true, session.EnabledFilters, sf);

        return string.Join(";", sql.SqlStrings);
    }
}

答案 2 :(得分:0)

过去,我能够通过SQL Profiler工具查看hibernate生成并发送给SQL的代码。根据您的目标,它可能能够满足您的需求。