How to obtain NHibernate generated SQL in code at runtime?
I know you can view the NHibernate generated SQL by hooking it up to log4net or piping it out to the console ("show_sql" option), but is there any way to obtain the generated SQL in code at runtime?
What I would like to be able to do is take an ICriteria object (or IQuery) and dump the generated SQL to the screen or custom log (not log4net). Something like...
var sql = criteria.GetGeneratedSql() // Wishful thinking
Can something like this be done?
EDIT: Thanks to DanP's excellent find of a "Hibernate Criteria to SQL Translation" class for Java, I took a first crack at porting this to NHibernate. Seems to work for simple cases, but definitely could use some improvement (i.e. error handling, etc.)
using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Impl;
using NHibernate.Loader;
using NHibernate.Loader.Criteria;
using NHibe开发者_如何学Pythonrnate.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;
}
}
Here is an article describing how to get the underlying sql from hql or criteria in Hibernate; I'd imagine porting this to use NHibernate wouldn't be too tricky:
http://narcanti.keyboardsamurais.de/hibernate-criteria-to-sql-translation.html
With NHibernate 3.2, this seems to work to get the SQL from an HQL query:
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);
}
}
In the past, I was able to view the code generated and sent to SQL by hibernate via the SQL Profiler tool. Depending on your goals, it may be able to provide what you need.
精彩评论