我知道你可以通过将它连接到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;
}
}
答案 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的代码。根据您的目标,它可能能够满足您的需求。