【发布时间】:2010-04-22 04:25:57
【问题描述】:
在代码的某些单元/集成测试中,我们希望检查我们的代码是否正确使用了二级缓存。
基于 Ayende 在此处提供的代码:
http://ayende.com/Blog/archive/2006/09/07/MeasuringNHibernatesQueriesPerPage.aspx
我为此编写了一个简单的类:
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;
}
}
}
预期用途:
using (var counter = QueryCounter.Start())
{
// ... do something
Assert.Equal(1, counter.QueryCount); // check the query count matches our expectations
}
但它总是返回 0 作为查询计数。没有记录任何 sql 语句。
但是,如果我使用 Nhibernate Profiler 并在我的测试用例中调用它:
NHibernateProfiler.Intialize()
NHProf 使用类似的方法从 NHibernate 捕获日志输出以通过 log4net 等进行分析。然后我的 QueryCounter 开始工作。
看起来我在代码中遗漏了一些东西来正确配置 log4net 以记录 nhibernate sql ... 有没有人知道我还需要做什么才能从 Nhibernate 获取 sql 日志记录输出?
附加信息:
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: 真
基于 jfneis 的响应,我编写了一个简单得多的类,它只使用 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};
}
}
启用统计信息后效果很好。
【问题讨论】:
-
在您的休眠配置中,您是否将 show_sql 设置为 true?请问您也可以发布您的 log4net.config 吗?
-
是的,尝试将 show_sql 设置为 true 和 false。虽然我认为 show_sql 没有使用 log4net,只是将 sql 语句转储到标准输出?我现在在最初的问题中包含了我的 log4net 配置。 NHibernateProfiler.Initialize() 然后导致我的类工作的事实向我表明,这可能是我缺少的一些编程 log4net 配置。
-
Bittercoder,我现在不在我的开发机器上,所以我不能发布代码,但是你有没有尝试使用统计来做到这一点?我也遇到过这种问题来测试 L2 和统计足以满足我的场景。回到办公室(从现在起 12 小时后)我会发布(如果仍然需要)一个完整的答案。希望这会有所帮助。
-
你在调用 log4net.Config.XmlConfigurator.Configure();你的应用什么时候启动?
-
应该是 。如果是这样,我会感到惊讶,只是想我会提到它。
标签: nhibernate caching count log4net nhprof