2009-08-12 14 views
8

Sto usando nHibernate ICriteria per eseguire una query e vorrei essere in grado di ottenere l'SQL che è stato eseguito dopo l'esecuzione dell'istruzione. Quindi per esempio ho qualcosa di simile.Esegui SQL da nHibernate

ISession session = NHibernateSessionManager.Instance.GetSession(); 
DetachedCriteria query = BuildCriteria(); // Goes away and constructs the ICriteria 
var result = query.GetExecutableCriteria(session).List<object>() 

// somehow here get the sql that was just run 
string sql = query.GetSqlSomehow(); 

so di poter accedere e vedere la SQL nel registro, ma voglio farlo subito dopo l'esecuzione della dichiarazione in modo da poter visualizzare l'SQL per l'utente (anche se non sembra bello).

+0

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

risposta

10

È possibile allegare un IInterceptor al proprio NH ISession, quindi utilizzare il metodo OnPrepareStatement() per intercettare lo (even modify) SQL.

+0

Mi piace questo metodo e iv hanno implementato la logica di intercettazione e attualmente intercettano il metodo SaveOrUpdate, ma da dove vado a prendere l'istruzione sql? Invocation.Request ...? – furier

0

Personalmente uso lo strumento "NHibernate Profiler" per questo. Vale la pena il prezzo poiché fa anche un buon lavoro analizzando il tuo utilizzo di NHibernate e notando potenziali problemi.

+0

Mi rendo conto che NHibernate Profiler è bravo in quello che fa, ma se leggi di nuovo la domanda non seguo un profiler o cerchi potenziali problemi. – Craig

+0

Ahhh quindi è necessario vedere l'SQL in fase di runtime? Stavo pensando che volevi solo vedere il vero SQL, che è quello che uso per gran parte del tempo. –

2

È possibile utilizzare la configurazione di Log4Net per acquisire l'SQL utilizzato. Per iniziare avresti bisogno di creare un appender personalizzato come questo:

using System; 
using System.Collections.Generic; 
using log4net.Appender; 
using log4net.Core; 

public class NHibernateQueryAppender : AppenderSkeleton 
{ 
     private static List<string> s_queries = new List<string>(); 
    private static int s_queryCount = 0; 

    public static IList<string> CurrentQueries 
    { 
      get { return s_queries.AsReadOnly(); } 
    } 

    public static int CurrentQueryCount 
    { 
     get { return s_queryCount; } 
    } 

    public static void Reset() 
    { 
     s_queryCount = 0; 
     s_queries.Clear(); 
    } 

    protected override void Append(LoggingEvent loggingEvent) 
    { 
     s_queries.Add(loggingEvent.RenderedMessage); 
     s_queryCount++; 
    } 
} 

Poi configurare log4net in questo modo:

<log4net> 
    <...other config...> 

    <appender name="nhquerycheck" type="NHibernateExecutor.Loggers.NHibernateQueryAppender, NHibernateExecutor" /> 

    <logger name="NHibernate.SQL"> 
     <level value="DEBUG"/> 
     <appender-ref ref="nhquerycheck" /> 
    </logger> 
</log4net> 

La classe di cui sopra può quindi essere interrogato in fase di esecuzione, come per visualizzare l'output sql sullo schermo


Modifica: per qualche motivo il post non è uscito corretto LY, così trovata esempio sul web http://nhforge.org/blogs/nhibernate/archive/2008/09/06/how-to-configure-log4net-for-use-with-nhibernate.aspx