Литмир - Электронная Библиотека
A
A

}

Операции агрегирования LINQ

Запросы LINQ могут также проектироваться для выполнения над результирующим набором разнообразных операций агрегирования. Одним из примеров может служить расширяющий метод

Count()
. Другие возможности включают получение среднего, максимального, минимального или суммы значений с использованием членов
Average()
,
Мах()
,
Min()
либо
Sum()
класса
Enumerable
. Вот простой пример:

Here is a simple example:static void AggregateOps()

{

  double[] winterTemps = { 2.0, -21.3, 8, -4, 0, 8.2 };

  // Разнообразные примеры агрегации.

  // Выводит максимальную температуру:

  Console.WriteLine("Max temp: {0}",

    (from t in winterTemps select t).Max());

  // Выводит минимальную температуру: 

  Console.WriteLine("Min temp: {0}",

    (from t in winterTemps select t).Min());

  // Выводит среднюю температуру:

  Console.WriteLine("Average temp: {0}",

    (from t in winterTemps select t).Average());

  // Выводит сумму всех температур:

  Console.WriteLine("Sum of all temps: {0}",

    (from t in winterTemps select t).Sum());

}

Приведенные примеры должны предоставить достаточный объем сведений, чтобы вы освоились с процессом построения выражений запросов LINQ. Хотя существуют дополнительные операции, которые пока еще не рассматривались, вы увидите примеры позже в книге, когда речь пойдет о связанных технологиях LINQ. В завершение вводного экскурса в LINQ оставшиеся материалы главы посвящены подробностям отношений между операциями запросов LINQ и лежащей в основе объектной моделью.

Внутреннее представление операторов запросов LINQ

К настоящему моменту вы уже знакомы с процессом построения выражений запросов с применением разнообразных операций запросов C# (таких как

from
,
in
,
where
,
orderby
и
select
). Вдобавок вы узнали, что определенная функциональность API-интерфейса LINQ to Objects доступна только через вызов расширяющих методов класса
Enumerable
. В действительности при компиляции запросов LINQ компилятор C# транслирует все операции LINQ в вызовы методов класса
Enumerable
.

Огромное количество методов класса

Enumerable
прототипированы для приема делегатов в качестве аргументов. Многие методы требуют обобщенный делегат по имени
Funс<>
, который был описан во время рассмотрения обобщенных делегатов в главе 10. Взгляните на метод
Where()
класса
Enumerable
, вызываемый автоматически в случае использования операции
where
:

<b>// Перегруженные версии метода Enumerable.Where&lt;T&gt;().</b>

<b>// Обратите внимание, что второй параметр имеет тип System.Func&lt;&gt;.</b>

public static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;(

  this IEnumerable&lt;TSource&gt; source,

  System.Func&lt;TSource,int,bool&gt; predicate)

public static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;(

  this IEnumerable&lt;TSource&gt; source,

  System.Func&lt;TSource,bool&gt; predicate)

Делегат

Func&lt;&gt;
представляет шаблон фиксированной функции с набором до 16 аргументов и возвращаемым значением. Если вы исследуете этот тип в браузере объектов Visual Studio, то заметите разнообразные формы делегата
Func&lt;&gt;
. Например:

<b>// Различные формы делегата Func&lt;&gt;.</b>

public delegate TResult Func&lt;T1,T2,T3,T4,TResult&gt;

                            (T1 arg1, T2 arg2, T3 arg3, T4 arg4)

public delegate TResult Func&lt;T1,T2,T3,TResult&gt;(T1 arg1, T2 arg2, T3 arg3)

public delegate TResult Func&lt;T1,T2,TResult&gt;(T1 arg1, T2 arg2)

public delegate TResult Func&lt;T1,TResult&gt;(T1 arg1)

public delegate TResult Func&lt;TResult&gt;()

Учитывая, что многие члены класса

System.Linq.Enumerable
при вызове ожидают получить делегат, можно вручную создать новый тип делегата и написать для него необходимые целевые методы, применить анонимный метод C# или определить подходящее лямбда-выражение. Независимо от выбранного подхода конечный результат будет одним и тем же.

Хотя использование операций запросов LINQ является, несомненно, самым простым способом построения запросов LINQ, давайте взглянем на все возможные подходы, чтобы увидеть связь между операциями запросов C# и лежащим в основе типом

Enumerable
.

Построение выражений запросов с применением операций запросов

Для начала создадим новый проект консольного приложения по имени

LinqUsingEnumerable
. В классе
Program
будут определены статические вспомогательные методы (вызываемые внутри операторов верхнего уровня) для иллюстрации разнообразных подходов к построению выражений запросов LINQ.

Первый метод,

QueryStringsWithOperators()
, предлагает наиболее прямолинейный способ создания выражений запросов и идентичен коду примера
LinqOverArray
, который приводился ранее в главе:

267
{"b":"847442","o":1}