Жесткая загрузка загруженных объектов в nHibernate с использованием ActiveRecord - PullRequest
4 голосов
/ 19 декабря 2008

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

Мы используем стек Castle (от монорельса до nHibernate с ActiveRecord).

Мы пометили агрегатные корни как ленивые [ActiveRecord(Lazy = true)] и настроили подпрограммы 'нетерпеливых' в нашем репозитории для нетерпеливого извлечения графа объектов. Мы используем HQL для определения активных выборок из нашей дочерней коллекции нашего корня,

например. если Account является агрегатным корнем (и отмечен как загруженный ленивый), мы будем стремиться получить Account .. Order .. Product сущностей для полного графа.

Так что никаких сюрпризов пока (надеюсь).

Теперь, если в приведенном выше примере Product также помечен [ActiveRecord(Lazy = true)], похоже, это останавливает директиву eager fetch в HQL.

Кто-нибудь знает способ принудительного извлечения лениво загруженного дочернего объекта ??

Приветствие Иэн

Обновление

Хорошо, вот некоторый пример hql. Используя пример из me.yahoo.com/../1 ниже, мы используем IMuliQuery для восстановления N + 1 зависимостей при выборке по отношениям «многие ко многим». Мы также явно используем классы отображения «многие ко многим». В результате наш hql:

from Account a 'm eager loading the graph
inner join fetch a.AccountsOrders ao 
inner join fetch ao.Order
from Account a 'm eager loading the graph
inner join fetch a.AccountAddresses aa
inner join fetch aa.Address ad
where a.ID = ?

... так что это выполняет операторы 2 sql и возвращает необходимый минимальный набор строк, и мы можем разрешить это в виде единого графа объектов. Ницца.

Но ... если, скажем, Address был отмечен как ленивый загруженный (а Order не был), доступ к Order не вызывает дальнейших операторов sql, а доступ к Address делает, несмотря на Факт, что оба загружены.

Так почему же лениво загруженная сущность Address, указанная выше, не стремится получить из вышеприведенного утверждения?

Ответы [ 3 ]

1 голос
/ 19 декабря 2008

Выполните «выборку внутреннего соединения» для сущности Account.Order.Product. Итак, вместо чего-то вроде этого (что у вас, вероятно, уже есть):

"from Account a inner join fetch a.Order where a.ID = ?"

Скажите ему, чтобы получить Заказ. Продукт также:

"from Account a inner join fetch a.Order inner join fetch a.Order.Product where a.ID = ?"
0 голосов
/ 17 июня 2009

Из «NHibernate в действии», стр. 225:

В настоящее время NHibernate ограничивает вас возможностью быстрой загрузки только одной коллекции.

Это может объяснить второй запрос на выборку адресов.

0 голосов
/ 13 февраля 2009

Зачем вам нетерпеливое поведение?

Все атрибуты Relationship в ActiveRecord имеют параметр 'Lazy =', который сообщает ActiveRecord о отложенной загрузке связанного объекта. Все кроме Принадлежностей. BelongsTo проверяет, имеет ли зависимый объект Lazy = true в своем атрибуте ActiveRecord, а затем создает прокси для объекта вместо выполнения выбора или объединения.

Чтобы ленивая загрузка работала, все методы и свойства экземпляра класса должны быть помечены как виртуальные. Это позволяет ActiveRecord создавать динамический прокси-класс.

Теперь может показаться хорошей идеей получить полный график производительности, но на практике это, вероятно, медленнее. У меня есть 3 веские причины, почему:

1.) BelongsTo имеет опцию Fetch, чтобы определить, как связаны объекты. FetchEnum.Join заставляет AR использовать соединение. FetchEnum. Select заставляет AR использовать отдельные операторы select для каждого объекта. Присоединения медленные, мы видим 10-кратное улучшение производительности от переключения на отдельные выборы. В клиентском коде нет никакой разницы между Lazy = true + FetchEnum.Select и eager.

2.) NHibernate делает кеширование. Если объект уже кэширован в сеансе или в кэше уровня 2, его можно загрузить из формы и избежать дополнительной работы.

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

...