Канал о разработке на платформе .NET с использованием языка программирования C#. Рассматриваются актуальные подходы и современные методологии разработки.
Очень круто получилось с последним вопросом! Сейчас расскажу 🙂
Я хотел сделать основной фокус на отложенном выполнении (Deferred Execution) запросов в LINQ. Что значит “отложенное выполнение”? А это значит, что LINQ-запрос будет исполнен только там, где будет востребован непосредственный результат его выполнения. На 3-ей строке мы не получаем непосредственный результат выполнения, так как переменная result имеет тип IQueryable<Trades>. Проще говоря, мы только определили некоторый запрос, результат выполнения которого, нам потребуется в будущем.
Где же мы получаем результат? А получаем мы его на строках 8, 9 и 10. То есть, мы обращаемся к базе данных аж 3 раза. Если вы не делаете лабу для универа, то это непозволительная роскошь для профессиональной разработки. Как избежать трехкратного обращения к базе данных? Очень просто, нужно сразу запросить результат путём вызова метода ToList(). Таким образом, на 8, 9 и 10 строках, мы будем оперировать с данными, которые будут находиться в оперативной памяти и за ними не нужно “ходить” в базу данных.
Подписчик Руслан Петряев дал точный ответ в комментариях 👍
Кроме того, Руслан увидел еще одну проблему, которая была вызвана запросом приведения к List. Посмотрите на код, а нужен ли нам вообще этот List? Ведь нам совершенно не нужны данные из этого списка. Всё что нам нужно – это общее число отфильтрованных записей, минимальная и максимальная цены. Тогда зачем мы держим эти данные в оперативной памяти? Всё что нам нужно по логике метода:
1. Обратиться к базе данных.
2. Забрать Count, MinPrice и MaxPrice для отфильтрованных записей.
3. Сохранить данные в объект TradeData и вернуть его.
Это можно сделать так:
TradeData result = DbContext.Set<Trades>
.Where(t => t.Status == TradeStatuses.Completed)
.GroupBy(t => t.Status == TradeStatuses.Completed)
.Select(t =>
new TradeData
{
PricesCount = t.Count(),
PriceMin = t.Min(r => r.Price),
PriceMax = t.Max(r => r.Price)
}).FirstOrDefault();
Супер! От вопроса получилась двойная польза для всех!
Всем хорошего вечера! 👋