Я довольно давно работаю с Fluent Nhibernate, но все еще чувствую, что мне не хватает чего-то важного и все время портится при построении более сложных запросов. Nhibernate должен быть очень оптимизирован и должен быть таким же быстрым, как простые SQL запросы, однако я все равно получаю намного лучшую производительность, используя хранимые процедуры вместо запросов Nhibernate.
Давайте возьмем пример:
return (from sm in session.Query<MinimumStocks>().Fetch(f => f.Articles).ToList()
select new MinimumStocksDO()
{
PlannedAmount = session.Query<Commisions>().Fetch(f => f.Operations).Where(w => w.Articles != null && w.Articles.ArtId == sm.Articles.ArtId && w.CommisionKind.Dessasembly == false).ToList().Sum(s =>
(Math.Max(**bunch of values here * *)),
Stock = session.Query<Stocks>().Where(w => w.Article == sm.Article && w.Storage.Public == false).Sum(s => s.TechnicalAmount ?? 0),
}).ToList();
Как видите, после взятия всех минимальных запасов при построении списка возврата мне нужно запросить кучу комиссионных, чтобы рассчитать запланированную сумму, и запасов, чтобы суммировать другую сумму. Неважно, что это такое. Конечно, важно то, что я делаю как минимум два запроса для каждой сущности в основном l oop.
На простом SQL Я бы использовал встроенный подзапрос для достижения этого, но как это сделать это более оптимизировано в Nhibernate Linq Query? Возможно ли это?
Вероятно, я могу написать другой подзапрос, используя ссылки вместо использования нового запроса.
return (from sm in session.Query<MinimumStocks>().Fetch(f => f.Articles).ToList()
select new MinimumStocksDO()
{
PlannedAmount = sm.Articles.Commisions.Where(w =>w.CommisionKind.Dessasembly== false).ToList().Sum(s =>
(Math.Max(**bunch of values here**)),
Stock = sm.Articles.Stocks.Where(w => w.Storage.Public == false).Sum(s => s.TechnicalAmount?? 0),
}).ToList();
Это имеет некоторое значение, но, безусловно, необходимо получить некоторые коллекции в начало, поэтому я изменил свой первоначальный запрос:
session.Query<MinimalStocks>().Fetch(f=>f.Articles).ThenFetch(f=>f.Commisions).AsEnumerable()
вроде бы в порядке ... но я также заинтересован в получении акций!
session.Query<MinimalStocks>().Fetch(f=>f.Articles).ThenFetch(f=>f.Commisions).Fetch(f=>f.Articles).ThenFetch(f=>f.Stocks).AsEnumerable()
и я получаю исключение
Невозможно одновременно доставить несколько пакетов.
, и моя оптимизация завершена.
КАК ПРАВИЛЬНО выполнять такие запросы?