NHibernate кэширование второго уровня с несколькими запросами

Мы широко используем функцию множественных запросов NHibernate и испытываем странное поведение. Похоже, что NHibernate не кэширует мультизапросы, и они всегда попадают в базу данных. Мы используем QueryOver, все запросы настроены для кэширования, но при тестировании домашней страницы с помощью http://blitz.io/ с -p 1-250:30 Я вижу, что единственный мультизапрос, попадающий в базу данных, выполняется более 2000 раз, тогда как другие запросы (например, выбор текущего зарегистрированного пользователя) выполняются только один или два раза.

Итак, вопрос: я что-то упустил или NHibernate на самом деле не кеширует результаты нескольких запросов?

1 ответ

Решение

Ага, понял! Как выяснилось, это была ошибка не всего кэша второго уровня, а, скорее, виноват наш способ использования QueryOver.

Поскольку мы пишем мультитенантное SaaS-приложение, большинство наших запросов выглядят так:

return
    Session.QueryOver<Article>().Cacheable().
        Where(a => a.Site == site && a.PublishedAt <= publishedAt).
        OrderByCoalesceDesc(typeof(DateTime), a => a.UpdatedAt, a => a.CreatedAt).
        Take(count).
        Future();

А также a.Site == site была проблема. Очевидно, способ кеширования запросов проверяет, кэшируются ли результаты запроса, или нет, в основном, используя комбинацию оператора SQL и всех параметров в качестве ключа к кешу "hashtable". Текст оператора SQL всегда одинаков для наших мультизапросов, но site параметр был виновником. NH проверяет, соответствуют ли все предоставленные параметры тем, которые уже находятся в кэше, и, естественно, у нас нет Equals() реализовано в нашем Site класс, поэтому проверка всегда не удалась.

В итоге мы переписали наши запросы так:

var siteID = site.ID;
return
    Session.QueryOver<Article>().Cacheable().
        Where(a => a.Site.ID == siteID && a.PublishedAt <= publishedAt)...
Другие вопросы по тегам