NHibernate: запрос критериев медленный в веб-приложении, но быстрый в модульных тестах, почему? - PullRequest
1 голос
/ 21 июля 2011

У меня проблема с тем, что запрос критерия в NHibernate выполняется менее чем за секунду, когда я запускаю его в модульном тесте, но когда я пытаюсь запустить его из контекста моего веб-приложения, это занимает более минуты , Оба используют одну и ту же базу данных для одних и тех же данных.

Мое сопоставление NHibernate:

var properties = new Dictionary<string, string>();
var configuration = new Configuration();

properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("proxyfactory.factory_class", "NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate");
properties.Add("connection.release_mode", "on_close");
properties.Add("current_session_context_class", "web");
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
properties.Add("connection.connection_string_name", "DBConnection");
configuration.Properties = properties;
SessionFactory = configuration.BuildSessionFactory();

Единственное различие в этом отображении между тестами и веб-приложением - это current_session_context_class, где в тестах он является thread_static, но, похоже, это не проблема.

Критерии для запроса:

var reports =   Session.CreateCriteria<Report>()
        .SetFetchMode("Site", FetchMode.Join)
        .SetFetchMode("Actions", FetchMode.Join)
        .SetResultTransformer(new DistinctRootEntityResultTransformer())
        .Add(Subqueries.PropertyIn("Site",
            SiteCriteria.GetSitesForUserWithPermission(user, Permission.SomePermission))))
        .List<Report>();

Я пытался использовать NH Profiler, чтобы помочь, но он не предлагал никаких полезных советов.

edit: заглядывая в nhprofiler, я вижу, что в тесте, например, длительность запроса составляет 1 мс / 313 мс (только для базы данных / всего). Но для веб-сайта это заняло у меня 1 мс / 43698 мс. Кажется, что NHibernate испытывает трудности с отображением реальных объектов.

Ответы [ 2 ]

4 голосов
/ 21 июля 2011

Разница между модульными тестами и веб-приложением заключается в том, что модульные тесты не регистрируются. Я добавил в наш log4net.config:

<filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="WARN" />
</filter>

И проблема ушла.

Он выводил много таких вещей:

2011-07-21 13:07:17,479 DEBUG [14] LoadContexts - attempting to locate loading collection entry [CollectionKey[Actions#d6adfe87-a7d4-4821-bb10-4ef76fcf614d]] in any result-set context
2011-07-21 13:07:17,481 DEBUG [14] LoadContexts - collection [CollectionKey[Actions#d6adfe87-a7d4-4821-bb10-4ef76fcf614d]] not located in load context
0 голосов
/ 17 августа 2011

Отладчик Visual Studio является виновником! Попробуйте запустить приложение с отключенной отладкой (ctrl + F5) или запустить его из-за пределов Visual Studio. Я сделал это, и мое приложение работало так же быстро, как и модульный тест.

Если это решит проблему, есть несколько вещей, которые вы можете сделать для ускорения VS Debugger, таких как удаление всех точек останова и удаление файла .suo. Для получения дополнительной информации см. Этот пост: Проблема медленной отладки в Visual Studio

Другие вещи, которые могут помочь:

  1. Попробуйте установить правильную базу данных по умолчанию для пользователя, к которому вы подключены. Сделайте это на самом сервере sql (например, используя SSMS), а не в любом из конфигов.
  2. Полностью отключите ведение журнала log4net, используя свойство threshold, как в app / web config: <log4net debug="false" threshold="off">.
  3. Установите default_schema в вашей конфигурации hibernate.
  4. Отключите show_sql в конфигурации hibernate.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...