Async / Await Multiple Linq Заявления - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть действие контроллера API, которое выполняет около 10 отдельных запросов linq, которые используются для формирования сводного объекта, который мне нужно отправить обратно клиенту.Все эти запросы linq выполняются для одних и тех же данных.Есть ли способ, которым я могу использовать async / await в этом сценарии, чтобы один оператор linq не должен блокировать выполнение других?Если да, какой самый эффективный способ написать этот асинхронный / ожидающий код?

Подводя итог моему вопросу:

  1. Есть ли у меня сценарий использования асинхронной / ожидающей в этом сценарии?
  2. Если это так, вместо того, чтобы создавать кучу независимых задач и затем помещать их все в Task.WhenAll (), есть более эффективный способ написать это, чтобы я мог легко добавить больше запросов linq позжена?(ничего слишком сумасшедшего, просто чистое и удобное в обслуживании).
[HttpGet]
public IActionResult GetInventoryDetails(string id)
{
    var inventory = _storeInventoryRepo.FindByCondition(s => s.Id = id)

    var uniqueProductCount = inventory.Select(x => x.ProductId).Distinct().ToList().Count

    var totalProductInventoryValue = inventory.Sum(x =>x.UnitPrice & x.TotalUnits)

    var cheapestProduct = inventory.OrderBy(x => x.unitPrice).Select(x => x.ProductId).First();

    var inventorydetails = new InventoryDetails
    {
       UniqueProductCount = uniqueProductCount,
       TotalProductInventoryValue = totalProductInventoryValue,
       CheapestProduct = cheapestProduct
    }

    Return Ok(inventoryDetails)
}

    public class ProductInventory
    {
        public string Id { get; set; }
        public string ProductId { get; set; }
        public int UnitPrice { get; set; }
        public double TotalUnits { get; set; }
    }

Как бы я использовал async / await, чтобы можно было выполнить uniqueProductCost, totalProductInventoryValue и самый дешевый продукт, не дожидаясь его завершения?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

У меня есть сценарий использования async / await в этом сценарии?

Если вы уверены, что хотите выполнять эти запросы к базе данных одновременно.

Обратите внимание, что многие клиенты баз данных ограничены одним запросом на соединение - в терминах EF это означает, что вам потребуется отдельный контекст БД для каждого запроса. Эта дополнительная сложность (и накладные расходы) может или не может стоить того; ты должен сам это определить.

Если это так, вместо того, чтобы создавать кучу независимых задач и затем помещать их все в Task.WhenAll (), есть ли более эффективный способ написать это, чтобы я мог позже легко добавить больше запросов linq? (ничего слишком сумасшедшего, просто чистый и ремонтопригодный).

Task.WhenAll будет самым чистым подходом. Вы можете передать List<Task> на Task.WhenAll, если это чище для вас.

Кроме того, как отмечено в комментариях, вы хотите использовать IQueryable<T>, а не IEnumerable<T>. Это связь с базой данных, которая должна быть асинхронной, и происходит в end выражения LINQ.

0 голосов
/ 29 апреля 2019

Поскольку вы работаете с IEnumerable<T>, а не с IQueriable<T>, вы не можете использовать async-await.

Если вы не используете Task.Run. Но, подобно использованию async-await с полностью асинхронными API (такими как ввод / вывод) в ASP.NET, вы жертвуете производительностью ради доступности, а использование Task.Run жертвует производительностью ради производительности.

Если вы используете Select(x => x.ProductId).Distinct(). Count(), вы будете выделять намного меньше и использовать гораздо меньше ресурсов ЦП, чем при использовании Select(x => x.ProductId).Distinct().ToList().Count.

То же самое касается использования inventory.OrderBy(x => x.unitPrice).First().ProductId вместо inventory.OrderBy(x => x.unitPrice).Select(x => x.ProductId).First().

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