Расширения Enumerable.GroupBy
и Queryable.GroupBy
имеют 8 перегрузок. Два из них (для Enumerable.GroupBy
):
// (a)
IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TKey, IEnumerable<TSource>, TResult> resultSelector);
// (b)
IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector,
Func<TKey, IEnumerable<TElement>, TResult> resultSelector);
(для Queryable.GroupBy
то же самое, только с Expression<Func<...
вместо Func<...
)
(b)
имеет дополнительный параметр elementSelector
.
В MSDN пример для перегрузки (a) и пример для перегрузки (b). Они оба работают с тем же примером исходной коллекции:
List<Pet> petsList = new List<Pet>
{
new Pet { Name="Barley", Age=8.3 },
new Pet { Name="Boots", Age=4.9 },
new Pet { Name="Whiskers", Age=1.5 },
new Pet { Name="Daisy", Age=4.3 }
};
Пример (a) использует этот запрос:
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age), // keySelector
(age, pets) => new // resultSelector
{
Key = age,
Count = pets.Count(),
Min = pets.Min(pet => pet.Age),
Max = pets.Max(pet => pet.Age)
});
И пример (b) использует этот запрос:
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age), // keySelector
pet => pet.Age, // elementSelector
(baseAge, ages) => new // resultSelector
{
Key = baseAge,
Count = ages.Count(),
Min = ages.Min(),
Max = ages.Max()
});
Результат обоих запросов точно такой же.
Вопрос 1: Есть ли какой-либо запрос, который я не могу выразить, используя только resultSelector
и где мне действительно понадобится elementSelector
? Или возможности двух перегрузок всегда эквивалентны, и это просто вопрос вкуса, чтобы использовать один или другой способ?
Вопрос 2: Есть ли дубликат двух разных перегрузок при использовании синтаксиса запроса LINQ?
(В качестве побочного вопроса: при использовании Queryable.GroupBy
с Entity Framework будут ли перегружены обе перегрузки в один и тот же SQL?)