2010-04-22 19 views
8

में NHibernate द्वारा निष्पादित प्रश्नों की संख्या की संख्या कोड के कुछ इकाई/एकीकरण परीक्षण में हम जांचना चाहते हैं कि दूसरे स्तर के कैश का सही उपयोग हमारे कोड द्वारा नियोजित किया जा रहा है।इकाई परीक्षण

Ayende यहाँ द्वारा प्रस्तुत कोड के आधार पर:

using (var counter = QueryCounter.Start()) 
{ 
    // ... do something 
    Assert.Equal(1, counter.QueryCount); // check the query count matches our expectations 
} 

:

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; 
     } 
    } 
} 
इरादा उपयोग के साथ

:

http://ayende.com/Blog/archive/2006/09/07/MeasuringNHibernatesQueriesPerPage.aspx

मैं सिर्फ इतना है कि करने के लिए एक साधारण क्लास लिखा था लेकिन यह हमेशा क्वेरी गिनती के लिए 0 देता है। कोई एसक्यूएल स्टेटमेंट लॉग नहीं किया जा रहा है।

लेकिन अगर मैं Nhibernate प्रोफाइलर का इस्तेमाल करते हैं और अपने परीक्षण के मामले में यह आह्वान:

NHibernateProfiler.Intialize() 

कहाँ NHProf एक समान दृष्टिकोण का उपयोग करता log4net के माध्यम से विश्लेषण के लिए NHibernate से प्रवेश उत्पादन पर कब्जा करने आदि तो मेरे QueryCounter काम करना शुरू करता ।

ऐसा लगता है कि लॉग इननेट को निबर्ननेट एसक्यूएल लॉगिंग के लिए सही तरीके से कॉन्फ़िगर करने के लिए मेरे कोड में कुछ याद आ रही है ... क्या किसी के पास निबर्ननेट से एसक्यूएल लॉगिंग आउटपुट प्राप्त करने के लिए मुझे और क्या करने की ज़रूरत है?

अतिरिक्त जानकारी:

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] &amp;lt;%P{user}&amp;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] &amp;lt;%P{user}&amp;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] &amp;lt;%P{user}&amp;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}; 
    } 
} 

आंकड़े सक्षम होने के बाद जो ठीक काम करता है।

+0

Bittercoder, मैं अपने देव मशीन से बाहर कर रहा हूँ अभी तो मैं कोड पोस्ट नहीं कर सकते, लेकिन आप ऐसा करने के लिए सांख्यिकी का उपयोग करने की कोशिश की है? मुझे एल 2 और सांख्यिकी का परीक्षण करने के लिए इस तरह की समस्या का सामना करना पड़ा है जहां मेरे परिदृश्य के लिए पर्याप्त है। कार्यालय में वापस (अब से 12h) मैं एक पूर्ण उत्तर पोस्ट (अगर अभी भी आवश्यक) पोस्ट करेंगे। उम्मीद है कि यह वहां तक ​​मदद करता है। – jfneis

+0

आपके निबर्ननेट कॉन्फ़िगरेशन में आपने show_sql को सत्य पर सेट किया है? कृपया आप अपना log4net.config भी पोस्ट कर सकते हैं? – mhanney

+0

हां, इसे show_sql सेट के साथ सही और गलत पर सेट करने की कोशिश की। हालांकि मैंने सोचा था कि show_sql ने log4net का उपयोग नहीं किया था और एसक्यूएल स्टेटमेंट को स्टडआउट पर छोड़ दिया था? मैंने अब प्रारंभिक प्रश्न में अपना लॉग 4नेट कॉन्फ़िगरेशन शामिल किया है। तथ्य यह है कि NHibernateProfiler.Initialize() तब मेरी कक्षा को काम करने का कारण बताता है कि यह शायद कुछ प्रोग्राममैटिक लॉग 4नेट कॉन्फ़िगरेशन है जो मुझे याद आ रही है। – Bittercoder

उत्तर

13

कैश मारा जा रहा है या यदि प्रश्न निष्पादित किए जा रहे हैं तो आंकड़ों का पालन करने के लिए एक और (सरल, आईएमओ) तरीका है: सांख्यिकी का उपयोग करना।

सबसे पहले, आप अपने राष्ट्रीय राजमार्ग कॉन्फ़िग फ़ाइल में आंकड़े सक्षम करने के लिए:

<property name="generate_statistics">true</property> 

उसके बाद, आप जब चाहें कैसे चीजें जा रहे हैं अपने सत्र कारखाने पूछ सकते हैं। आप L2 कैश परीक्षण के बारे में बात की है, तो आप ऐसा ही कुछ हो सकता है:

 sessionFactory.Statistics.QueryExecutionCount; 
     sessionFactory.Statistics.TransactionCount; 
:

 // act 
     MappedEntity retrievedEntity = session.FindById(entity.Id); 
     long preCacheCount = sessionFactory.Statistics.SecondLevelCacheHitCount; 
     retrievedEntity = session.FindById(entity.Id); 
     long postCacheCount = sessionFactory.Statistics.SecondLevelCacheHitCount; 
     // assert 
     Assert.AreEqual(preCacheCount + 1, postCacheCount); 

लेकिन, अगर आप वास्तव में क्या चाहते हैं क्वेरी गिनती है, वहाँ सांख्यिकी इंटरफ़ेस में बहुत सारे अन्य विकल्प हैं

ठीक है, यही वह है। उम्मीद है कि यह मेरी मदद के रूप में आपकी मदद करता है।

सादर,

फिलिपे

+0

मैंने आँकड़ों को एक नज़र दिया, और मुझे कोई प्रश्न आंकड़े नहीं मिला - लेकिन मैं आईएसशनस्टैटिक्स, आईएसशन फैक्ट्री। स्टेटिक्स (आईएसटीटिक्स) देख रहा था। इसे जाने देंगे :) – Bittercoder

+0

आंकड़ों का उपयोग करके सरल वर्ग कार्यान्वित - महान काम करता है - मदद जोसे के लिए धन्यवाद! – Bittercoder

+0

मुझे यह जानकर खुशी हुई कि इससे आपकी मदद मिली। – jfneis

संबंधित मुद्दे