Dans certains tests unitaires/d'intégration du code, nous souhaitons vérifier que l'utilisation correcte du cache de second niveau est utilisée par notre code.Nombre de requêtes exécutées par NHibernate dans un test unitaire
Basé sur le code présenté par Ayende ici:
http://ayende.com/Blog/archive/2006/09/07/MeasuringNHibernatesQueriesPerPage.aspx
j'ai écrit une classe simple pour faire cela:
public class QueryCounter : IDisposable
{
CountToContextItemsAppender _appender;
public int QueryCount
{
get { return _appender.Count; }
}
public void Dispose()
{
var logger = (Logger) LogManager.GetLogger("NHibernate.SQL").Logger;
logger.RemoveAppender(_appender);
}
public static QueryCounter Start()
{
var logger = (Logger) LogManager.GetLogger("NHibernate.SQL").Logger;
lock (logger)
{
foreach (IAppender existingAppender in logger.Appenders)
{
if (existingAppender is CountToContextItemsAppender)
{
var countAppender = (CountToContextItemsAppender) existingAppender;
countAppender.Reset();
return new QueryCounter {_appender = (CountToContextItemsAppender) existingAppender};
}
}
var newAppender = new CountToContextItemsAppender();
logger.AddAppender(newAppender);
logger.Level = Level.Debug;
logger.Additivity = false;
return new QueryCounter {_appender = newAppender};
}
}
public class CountToContextItemsAppender : IAppender
{
int _count;
public int Count
{
get { return _count; }
}
public void Close()
{
}
public void DoAppend(LoggingEvent loggingEvent)
{
if (string.Empty.Equals(loggingEvent.MessageObject)) return;
_count++;
}
public string Name { get; set; }
public void Reset()
{
_count = 0;
}
}
}
Avec l'usage prévu:
using (var counter = QueryCounter.Start())
{
// ... do something
Assert.Equal(1, counter.QueryCount); // check the query count matches our expectations
}
Mais il renvoie toujours 0 pour le nombre de requêtes. Aucune instruction SQL n'est en cours de journalisation.
Toutefois, si je utilise Nhibernate Profiler et invoquez dans mon cas test:
NHibernateProfiler.Intialize()
Où NHProf utilise une approche similaire pour capturer la sortie de l'enregistrement de NHibernate pour l'analyse par log4net etc. alors mon QueryCounter commence à travailler . Il semble qu'il me manque quelque chose dans mon code pour que log4net soit correctement configuré pour la journalisation de nhibernate sql ... Quelqu'un a-t-il des pointeurs sur ce que je dois faire pour obtenir la sortie de journalisation sql de Nhibernate?
Informations complémentaires:
logging.config:
<log4net>
<appender name="trace" type="log4net.Appender.TraceAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%P{user}&gt; - %m%n" />
</layout>
</appender>
<appender name="console" type="log4net.Appender.ConsoleAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%P{user}&gt; - %m%n" />
</layout>
</appender>
<appender name="debug" type="log4net.Appender.DebugAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%P{user}&gt; - %m%n" />
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</logger>
<root>
<priority value="DEBUG" />
<appender-ref ref="trace" />
<appender-ref ref="console" />
<appender-ref ref="debug" />
</root>
</log4net>
show_sql: true
Sur la base de jfneis réponse, je l'ai écrit une classe beaucoup plus simple qui utilise simplement les statistiques de l'usine de NHibernate:
public class QueryCounter
{
long _startCount;
QueryCounter()
{
}
public int QueryCount
{
get { return (int) (UnitOfWork.CurrentSession.SessionFactory.Statistics.QueryExecutionCount - _startCount); }
}
public static QueryCounter Start()
{
return new QueryCounter {_startCount = UnitOfWork.CurrentSession.SessionFactory.Statistics.QueryExecutionCount};
}
}
Ce qui fonctionne très bien une fois les statistiques activées.
Bittercoder, je suis sur ma machine dev en ce moment donc je ne peux pas poster code, mais avez-vous essayé d'utiliser des statistiques pour le faire? J'ai également fait face à ce genre de problème pour tester L2 et les statistiques où assez à mon scénario. Retour au bureau (12h à partir de maintenant) Je posterai (si nécessaire) une réponse complète. J'espère que cela aide jusqu'à là. – jfneis
Dans votre configuration nhibernate avez-vous défini show_sql sur true? Pouvez-vous également poster votre fichier log4net.config? – mhanney
Oui, essayé avec show_sql mis à vrai et faux. Bien que je pensais que show_sql n'utilisait pas log4net et juste jeté les instructions SQL à stdout? J'ai maintenant inclus ma configuration log4net dans la question initiale. Le fait que NHibernateProfiler.Initialize() fasse ensuite fonctionner ma classe me suggère que c'est probablement une configuration log4net programmatique qui me manque. – Bittercoder