分組運算符的作用與SQL查詢的GroupBy子句相同。分組運算符根據給定的鍵創(chuàng)建一組元素。該組包含在實現(xiàn)IGrouping <TKey,TSource>接口的特殊類型的集合中,其中TKey是鍵值,在其上已形成該組,TSource是與該分組鍵值匹配的元素的集合。
| 分組運算符 | 描述 |
|---|---|
| GroupBy | GroupBy操作符根據某個鍵值返回元素組。每個組由 IGrouping<TKey,TElement>對象表示。 |
| ToLookup | ToLookup 與 GroupBy 相同; 唯一的區(qū)別是 GroupBy 的執(zhí)行被延遲,而 ToLookup 的執(zhí)行是立即的。 |
GroupBy運算符基于某個鍵值從給定集合返回一組元素。每個組由IGrouping <TKey,TElement>對象表示。另外,GroupBy方法有8個重載方法,因此您可以根據需要在方法語法中使用適當的擴展方法。
LINQ查詢可以以GroupBy或Select子句結尾。
GroupBy運算符的結果是組的集合。例如,GroupBy從Student集合返回IEnumerable <IGrouping <TKey,Student >>:

下面的示例創(chuàng)建一組年齡相同的學生。年齡相同的學生將在同一集合中,每個分組的集合將具有一個密鑰和內部集合,其中密鑰將是年齡,內部集合將包括年齡與密鑰匹配的學生。
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};
var groupedResult = from s in studentList
group s by s.Age;
//遍歷每組
foreach (var ageGroup in groupedResult)
{
Console.WriteLine("Age Group: {0}", ageGroup .Key); //每組都有一個鑰匙
foreach(Student s in ageGroup) // 每組都有內部收藏
Console.WriteLine("Student Name: {0}", s.StudentName);
}AgeGroup: 18 StudentName: John StudentName: Bill AgeGroup: 21 StudentName: Steve StudentName: Abram AgeGroup: 20 StudentName: Ram
如上例所示,您可以使用“ foreach”循環(huán)對組進行迭代,其中每個組都包含一個鍵和內部集合。下圖顯示了調試視圖中的結果。

如下所示,在VB.Net中,將“Into Group”與中的“Group By”子句一起使用。
Dim groupQuery = From s In studentList
Group By s.Age Into Group
For Each group In groupQuery
Console.WriteLine("Age Group: {0}", group.Age) // 每個組都有關鍵屬性名稱
For Each student In group.Group // 每組都有內部收藏
Console.WriteLine("Student Name: {0}", student.StudentName)
Next
Next請注意,每個組都有一個執(zhí)行該組的屬性名稱。在上面的示例中,我們使用Age來組成一個組,因此每個組將使用“ Age”屬性名稱而不是“ Key”作為屬性名稱。
AgeGroup: 18 StudentName: John StudentName: Bill AgeGroup: 21 StudentName: Steve StudentName: Abram AgeGroup: 20 StudentName: Ram
GroupBy()擴展方法工作在方法的語法一樣。在GroupBy擴展方法中為鍵選擇器字段名稱指定lambda表達式。
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};
var groupedResult = studentList.GroupBy(s => s.Age);
foreach (var ageGroup in groupedResult)
{
Console.WriteLine("Age Group: {0}", ageGroup.Key); //每組都有一個鑰匙
foreach(Student s in ageGroup) //每個組都有一個內部集合
Console.WriteLine("Student Name: {0}", s.StudentName);
}Dim groupQuery = studentList.GroupBy(Function(s) s.Age)
For Each ageGroup In groupQuery
Console.WriteLine("Age Group: {0}", ageGroup.Key) //每組都有一個鑰匙
For Each student In ageGroup.AsEnumerable() //每個組都有一個內部集合
Console.WriteLine("Student Name: {0}", student.StudentName)
Next
NextAgeGroup: 18 StudentName: John StudentName: Bill AgeGroup: 21 StudentName: Steve StudentName: Abram AgeGroup: 20 StudentName: Ram
ToLookup與GroupBy相同;唯一的區(qū)別是GroupBy執(zhí)行被推遲,而ToLookup執(zhí)行是立即執(zhí)行。另外,ToLookup僅適用于方法語法。查詢語法不支持 ToLookup。
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};
var lookupResult = studentList.ToLookup(s => s.age);
foreach (var group in lookupResult)
{
Console.WriteLine("Age Group: {0}", group.Key); //每組都有一個鍵
foreach(Student s in group) //每個組都有一個內部集合
Console.WriteLine("Student Name: {0}", s.StudentName);
}Dim loopupResult = studentList.ToLookup(Function(s) s.Age)
GroupBy&ToLookup返回一個具有鍵和基于鍵字段值的內部集合的集合。
GroupBy 延遲執(zhí)行,而 ToLookup 立即執(zhí)行。
LINQ查詢語法可以以GroupBy或Select子句結尾。