Количество количества запросов, выполняемых NHibernate в модульном тесте

В некоторой единице/интеграционных тестах кода мы хотим проверить, что корректное использование второго кэша уровня используется нашим кодом.

На основе кода, представленного 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 и вызываю это в моем тестовом сценарии:

NHibernateProfiler.Intialize()

Где NHProf использует аналогичный подход для получения вывода входа от NHibernate для анализа через log4net и т.д. затем, мой QueryCounter начинает работать.

Похоже, что я пропускаю что-то в своем коде для получения log4net, настроенного правильно для входа nhibernate sql... у кого-либо есть какие-либо указатели на том, что еще я должен сделать для получения sql вход вывода от Nhibernate?

Дополнительная информация:

Logging.config:



  
    
      
    
  

  
    
      
    
  

  
    
      
    
  

  
    
    
  

  
    
    
    
    
  


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};
  }
}

Который работает просто великолепно, после того как статистика включена.

8
задан Bittercoder 23 April 2010 в 23:57
поделиться

1 ответ

Есть другой (более простой, IMO) способ проверить, происходит ли попадание в кеш или выполняются ли запросы: использование статистики.

Прежде всего, вы должны включить статистику в вашем конфигурационном файле NH:

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

После этого вы можете спрашивать свою фабрику сеансов в любое время, когда захотите, как идут дела. Вы говорили о тестировании кэша L2, так что у вас может быть что-то вроде этого:

        // 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);

Но, если вам действительно нужен счетчик запросов, в интерфейсе статистики есть много других опций:

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

Ну, вот и все. Надеюсь, это поможет вам, как помогло мне.

С уважением,

Филипе

13
ответ дан 5 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: