извлекать множественные вложенные ассоциации с помощью nhibernate (и queryover) - PullRequest
3 голосов
/ 24 мая 2011

У меня есть база данных, которая имеет несколько вложенных партнеров. В основном, структура выглядит следующим образом:

Order -> OrderItem -> OrderItemPlaylist -> OrderPlaylistItem -> Track -> Artist

Мне нужно сгенерировать отчет на основе всех заказов, проданных за определенную дату, который должен перейти на ВСЕ упомянутые ассоциации для получения необходимой информации.

Попытка объединить все таблицы вместе была бы излишним, так как это привело бы к чрезвычайно большому декартовому объединению со многими избыточными данными, учитывая, что это объединит 6 таблиц вместе. Код ниже:

q.Left.JoinQueryOver<OrderItem>(order => order.OrderItems)
     .Left.JoinQueryOver<OrderItemPlaylist>(orderItem => orderItem.Playlist)
     .Left.JoinQueryOver<OrderItemPlaylistItem>(orderItemPlaylist => orderItemPlaylist.PlaylistItems)
     .Left.JoinQueryOver<Track>(orderItemPlaylistItem => orderItemPlaylistItem.Track)
     .Left.JoinQueryOver<Artist>(track => track.Artist)

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

Есть идеи, что будет лучшим и наиболее эффективным подходом? В настоящее время я пытался включить пакетную загрузку, которая значительно сокращает количество запросов к базе данных, но все же не кажется мне хорошим подходом, а скорее «простым обходным путем».

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

Кроме того, это не обязательно относится к QueryOver, поскольку я могу получить доступ к .RootCriteria и использовать Criteria API.

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

0 голосов
/ 27 июня 2011

Вероятно, вам следует начать с определения запроса как можно лучше в SQL и рассмотрения планов выполнения, чтобы найти самый лучший метод (и достаточно ли ваших индексов).

В этот момент вы знаете, для чего стреляете, и тогда довольно просто попробовать написать код в HQL или QueryOver или даже LINQ и проверить результаты с помощью средства записи SQL в NHibernate или превосходного NHProfiler http://www.nhprof.com.

Вы, вероятно, правы, когда нам понадобилось несколько запросов. Ускорьте их, упаковав как можно больше (которые не зависят друг от друга) в отдельные поездки, используя команду «Future» в Criteria или QueryOver. Подробнее об этом можно прочитать здесь: http://ayende.com/blog/3979/nhibernate-futures

0 голосов
/ 20 августа 2011

Я считаю, что это то, что вы ищете

http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

0 голосов
/ 26 мая 2011

Если вы предпочитаете один SQL-запрос, какой синтаксис SQL вы ожидаете получить? Я полагаю, что вы не можете избежать длинной последовательности JOIN с, если собираетесь использовать один SQL-запрос.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...