2010-07-20 9 views
9

Sé que usted puede ver el SQL generado por NHibernate conectarlo a log4net o se conducirá a la consola (opción "show_sql"), pero ¿hay alguna manera de obtener el SQL generado en el código en tiempo de ejecución?¿Cómo obtener NHibernate SQL generado en código en tiempo de ejecución?

Lo que me gustaría hacer es tomar un objeto ICriteria (o IQuery) y volcar el SQL generado en la pantalla o el registro personalizado (no log4net). Algo como ...

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

¿Se puede hacer algo como esto?


EDIT: Gracias a excelente hallazgo de una clase "Hibernate Criteria to SQL Translation" para Java DanP 's, me tomaron una primera grieta en portar este a NHibernate. Parece que funciona para los casos simples, pero sin duda podría mejorar (es decir, tratamiento de errores, etc.)

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; 
    } 
} 
+1

http: //stackoverflow.com/questions/10704462/how-can-i-have-nhibernate-only-generate-the-sql-without-executing-it –

Respuesta

5

Aquí es un artículo que describe cómo obtener el SQL subyacente de HQL o criterios en Hibernate; Me imagino portar esta opción para utilizar NHibernate no sería demasiado complicado:

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

+0

gran hallazgo, he estado buscando una solución clara y simple .... ahora sólo tengo que puerto esta a NHibernate – Jaguar

+0

@Jaguar: de acuerdo, es bastante resbaladiza ... puede simplemente que la carrera para un puerto;) – DanP

+0

@DanP muy fresco. No puedo creer que algo como esto no está "construido en" – WayneC

0

En el pasado, yo era capaz de ver el código generado y enviado a SQL hibernación a través del Analizador de SQL herramienta. Dependiendo de sus objetivos, es posible que pueda proporcionarle lo que necesita.

2

Con NHibernate 3.2, esto parece funcionar para obtener el SQL de una consulta HQL:

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); 
    } 
} 
Cuestiones relacionadas