2012-05-22 11 views
43

So come registrare l'SQL nella finestra log4net/NLog/trace in fase di esecuzione con l'opzione di configurazione show_sql.Come posso fare in modo che NHibernate generi solo l'SQL senza eseguirlo?

Quello che sto cercando è un modo per dare un Query<T>() a NHibernate recuperare l'SQL generato.

Ho esaminato la classe Persister, i Driver, diversi Interceptor ed Eventi. Ci sono così tanti posti da guardare, anche restringere la mia ricerca sarebbe di grande aiuto.

+0

Quello che sto cercando di realizzare è profiler di un uomo povero di sorta. Voglio solo sapere come valuterà una determinata query linq da un pezzo di codice di test. – hometoast

risposta

84

è possibile ottenere la query SQL generati senza esecuzione con i seguenti metodi:

Per le query NHibernate.Linq:

public String GetGeneratedSql(System.Linq.IQueryable queryable, ISession session) 
{ 
    var sessionImp = (ISessionImplementor) session; 
    var nhLinqExpression = new NhLinqExpression(queryable.Expression, sessionImp.Factory); 
    var translatorFactory = new ASTQueryTranslatorFactory(); 
    var translators = translatorFactory.CreateQueryTranslators(nhLinqExpression, null, false, sessionImp.EnabledFilters, sessionImp.Factory); 

    return translators[0].SQLString; 
} 

Per le query Criteri:

public String GetGeneratedSql(ICriteria criteria) 
{ 
    var criteriaImpl = (CriteriaImpl) criteria; 
    var sessionImpl = (SessionImpl) criteriaImpl.Session; 
    var factory = (SessionFactoryImpl) sessionImpl.SessionFactory; 
    var implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName); 
    var loader = new CriteriaLoader((IOuterJoinLoadable) factory.GetEntityPersister(implementors[0]), factory, criteriaImpl, implementors[0], sessionImpl.EnabledFilters); 

    return loader.SqlString.ToString(); 
} 

Per QueryOver query:

public String GetGeneratedSql(IQueryOver queryOver) 
{ 
    return GetGeneratedSql(queryOver.UnderlyingCriteria); 
} 

Per HQL interroga:

public String GetGeneratedSql(IQuery query, ISession session) 
{ 
    var sessionImp = (ISessionImplementor)session; 
    var translatorFactory = new ASTQueryTranslatorFactory(); 
    var translators = translatorFactory.CreateQueryTranslators(query.QueryString, null, false, sessionImp.EnabledFilters, sessionImp.Factory); 

    return translators[0].SQLString; 
} 
+0

C'è un modo per farlo per le query HQL? –

+0

Aggiornato la mia risposta con query hql. – Gerard

+1

@ Gerard Ho messo in circolazione la tua risposta molto utile. Hai idea se questo è possibile per INSERTs - UPDATEs? Vedi http://stackoverflow.com/questions/10786934/how-can-i-get-nhibernate-to-give-me-the-sql-it-would-generate-for-an-insert-up Grazie! –

1

In base alla versione di NHibernate 3.4 il metodo di espressione LINQ è:

public String GetGeneratedSql(System.Linq.IQueryable queryable, ISession session) 
     { 
     var sessionImp = (ISessionImplementor)session; 
     var nhLinqExpression = new NhLinqExpression(queryable.Expression,    
            sessionImp.Factory); 
     var translatorFactory = new ASTQueryTranslatorFactory(); 
     var translators = translatorFactory.CreateQueryTranslators(nhLinqExpression.Key, nhLinqExpression, null, false, 
                   sessionImp.EnabledFilters, sessionImp.Factory); 

     var sql = translators.First().SQLString; 
     var formamttedSql = FormatStyle.Basic.Formatter.Format(sql); 
     int i = 0; 
     var map = ExpressionParameterVisitor.Visit(queryable.Expression, sessionImp.Factory).ToArray(); 
     formamttedSql = Regex.Replace(formamttedSql, @"\?", m => map[i++].Key.ToString().Replace('"', '\'')); 

     return formamttedSql; 
     } 
+0

Esiste anche un modo per convertire una stringa sql in un hql o in una queryover? – Franki1986

Problemi correlati