запрос nhibernate3 - коллекции с коллекциями - PullRequest
1 голос
/ 05 января 2012

У меня есть несколько выпадающих меню на моей веб-странице. Они связаны и имеют похожую структуру классов с двунаправленной связью.

Другими словами: у класса Alpha есть список класса Beta, у которого, в свою очередь, есть список класса Charlie. У каждого класса Beta также есть свой собственный список Alpha (к которому он принадлежит), и у каждого класса Charlie есть свой собственный список Beta.

Я использую NHibernate 3 с беглым nhibernate и autoppings.

Теперь. Если бы я просто запустил

session.CreateCriteria<Alpha>().SetMaxResults(1000).List<Alpha>();

Я получаю проблему N + 1, когда перебираю коллекции.

На мой взгляд, следующие SQL-запросы - это все, что запрашивается в базе данных

select top 1000 * from Alpha
select top 1000 * from Beta
select top 1000 * from Charlie
select * from Alpha2Beta
select * from Beta2Charlie

Но как мне написать запрос, чтобы это работало ??

Ответы [ 3 ]

1 голос
/ 05 января 2012

Есть хороший трюк, который Айенде показал в своем блоге.Я не пробовал это лично, так как решил изменить свой BL, чтобы избежать этой проблемы, поэтому возьмите это с собой.

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

0 голосов
/ 06 января 2012

Насколько я знаю, вы не можете помочь с запросом по уровню запроса, как вы можете с извлечением из объединения. Однако, если вы измените mappings и установите режим извлечения по умолчанию для связей как «подзапрос», вы можете быть приятно удивлены:

Из документации Hibernate (одинаково хорошо работает с NHibernate):

С помощью fetch = "subselect" в коллекции вы можете указать Hibernate не только загрузить это коллекция во втором SELECT (или ленивая или не ленивая), но также и все другие коллекции для всех «владеющих» сущностей, которые вы загрузили в первый SELECT. Это особенно полезно для выборка нескольких коллекций параллельно "

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

Тем не менее, если вы загружаете 1К сущностей и ожидаете, что ассоциации будут иметь более пары записей каждая, вы, вероятно, просто собираетесь перейти от (ВЫБРАТЬ N + 1) ^ 2 к "святому" дерьмо я просто загрузил всю базу данных в память ". ; -)

(Обратите внимание: если вы делаете это и у вас есть сценарий, в котором вы загружаете список альфа, но вам нужны только связанные бета-версии для одной альфы, вы все равно собираетесь загрузить все из них, и вы ничего не можете с этим поделать На практике, однако, я обнаружил, что это очень редкий сценарий, поэтому обычно выборочный выбор мне очень подходит.)

0 голосов
/ 05 января 2012

Если вы используете Критерии, вам нужно включить Dyanmic Fetching вызовы методов.

...