Стандартные операторы запроса с LINQ - Статистические выражения, иерархии и проекции
ОГЛАВЛЕНИЕ
Статистические выражения, иерархии и проекции
Применение статистических операторов, таких как Sum, в методе «LINQ — сущности» может значительно упростить запрос. Например, следующий фрагмент кода позволяет получить последовательность заказов на общую сумму более 10 000 долларов США:
using (Entities entities = new Entities())
{
var query = from o in entities.Orders
where o.OrderDetails.Sum(
od => od.UnitPrice * od.Quantity) >= 10000
select o;
foreach (Orders order in query)
Console.WriteLine(order.OrderID);
}
Поскольку LINQ позволяет выполнять запросы по иерархическим коллекциям сущностей, стандартные операторы запросов тоже могут применяться ко вложенным последовательностям. Это может пригодиться в том случае, если нужно выполнять вычисления с производными данными или опрашивать их. Производные данные существуют только в форме набора базовых данных. В качестве примера можно привести заказы, в данных которых указана только цена и количество. Общая сумма заказа нигде не указывается. Применяя оператор Sum к запросу LINQ, можно, к примеру, получить список клиентов, потративших более 20 000 долларов на заказы:
using (Entities entities = new Entities())
{
var query = from c in entities.Customers
where c.Orders.Sum(
o => o.OrderDetails.Sum(
od => od.UnitPrice * od.Quantity)) >= 25000
select c;
foreach (Customers customer in query)
Console.WriteLine(customer.CompanyName);
}
Этот пример показывает порядок применения стандартных операторов на различных уровнях запроса LINQ. В конечном итоге запрос возвращает последовательность сущностей Customer, но для этого нужно сначала проникнуть в данные, составляющие заказ, и получить сведения, необходимые для расчета стоимости каждой позиции, просуммировать позиции в каждом заказе, а потом сложить итоговые суммы по заказам каждого отдельно взятого клиента.
Оператор Count — еще один пример стандартного статистического оператора. Он позволяет, к примеру, узнать количество клиентов, потративших более 25 000 долларов:
using (Entities entities = new Entities())
{
var query = (from c in entities.Customers
where c.Orders.Sum(
o => o.OrderDetails.Sum(
od => od.UnitPrice * od.Quantity)) >= 25000
select c).Count();
Console.WriteLine(query);
}
Оператор Max можно использовать для того, чтобы определить лучшего клиента компании. Следующий фрагмент кода возвращает сумму, которую потратил самый расточительный клиент. Здесь используется сочетание статистических операторов Sum и Max на различных уровнях иерархии:
using (Entities entities = new Entities())
{
var query = (from c in entities.Customers
select new
{
c.CustomerID,
Total = c.Orders.Sum(
o => o.OrderDetails.Sum(od => od.UnitPrice))
}).Max(c2 => c2.Total);
Console.WriteLine(query);
}