Нетерпеливая загрузка ленивых загружаемых объектов в nHibernate с использованием ActiveRecord

StackOverflow https://stackoverflow.com/questions/380568

Вопрос

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

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

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

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

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

Теперь, если в приведенном выше примере Продукт также отмечен [ActiveRecord(Lazy = true)], похоже, это останавливает директиву нетерпеливой выборки в 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 = ?

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

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

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

Это было полезно?

Решение

Почему вам нужно нетерпеливое поведение?

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

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

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

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

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

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

Другие советы

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

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

Скажите ему также получить Order.Product:

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top