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查询语法时,是否有这两个不同重载的对应方法?
(附带问题:当使用Entity Framework的Queryable.GroupBy
时,这两个重载会被转换为完全相同的SQL吗?)