2011-02-04 4 views
0

У моих DTO есть идентификатор, который используется моей базой данных, обычно с автоматическим инкрементом INT. Мое приложение, в общем, никогда не заботится об этом поле идентификатора, оно имеет тенденцию искать DTO по свойству Name. Который дал этот метод в моем слое доступа к данным:nHibernate Session.Load по названию свойства

public T GetByName(string name) 
{ 
    return (T) Session 
     .CreateCriteria(typeof (T)) 
     .Add(Expression.Eq("Name", name)) 
     .UniqueResult(); 
} 

Теперь, что я заметил, так это то, как я загружаю подавляющее большинство моих DTOS, что NHibernate не кэшировать результат. Я смог наблюдать через SQL Profiler, что каждый вызов этого метода приводит к обратному соединению с базой данных, даже если я уверен, что загрузил этот конкретный объект во время моей единицы работы (HTTP-транзакция).

Кроме того, я прочитал, что nHibernate будет кэшировать DTO в кеше 1-го уровня при вызове .Load().

Итак, мой вопрос: есть ли способ сконфигурировать nHibernate, чтобы поместить мои DTO в кеш 1-го уровня после загрузки таким образом или мне нужно найти другой способ уменьшить количество обращений к базе данных?

ответ

2

С кодом возникает несколько проблем.

  1. Критерии будут всегда перейти к БД, если вы не кэшировать запрос. Вам необходимо использовать SetCacheable, настроить поставщика кеша и enable query caching.
  2. Даже если вы кешируете запрос, вам все равно нужно также make the entity cacheable, потому что NHibernate хранит идентификаторы объектов, полученные в результате этого запроса, но не сами сущности.
  3. Так называемый «кеш 1-го уровня» - это единица работы (сеанс). Вы взаимодействуете с ним, используя методы Get и Load, а не запросы. Небольшое исключение: объектов, которые уже загружены в сеанс, не нужно будет читать из БД еще раз.
0

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

У меня была такая же ситуация некоторое время назад. Я никогда не устанавливал, будут ли объекты, не загруженные первичным ключом, кэшироваться в кеше второго уровня (если вы используете его). Возможно, кто-то другой может дать ответ.

+0

То, что кэшируется в кэше второго уровня, определяется с помощью конфигурации кэша второго уровня. В этом случае необходимо будет включить кеширование результатов, поскольку вы действительно выполняете запрос для извлечения объекта. –

0

Как насчет определения натурального идентификатора в качестве поля имени? Я не знаю, будет ли nHibernate просто использовать это только для генерации схемы, но имеет смысл, что это естественное место для определения этого, независимо от того, что nHibernate действительно будет с ним делать. Если нет, это не плохой запрос функции.

Смежные вопросы