Оптимизация запросов Nhibernate Fluent Query и получение многослойных пакетов - PullRequest
0 голосов
/ 04 августа 2020

Я довольно давно работаю с 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()

и я получаю исключение

Невозможно одновременно доставить несколько пакетов.

, и моя оптимизация завершена.

КАК ПРАВИЛЬНО выполнять такие запросы?

...