LINQ查询表达式(3) - LINQ 查询分组
对查询结果进行分组
分组是 LINQ 最强大的功能之一。
下面的示例演示如何以各种方式对数据进行分组:
- 按照单个属性。
- 按照字符串属性的首字母。
- 按照计算出的数值范围。
- 按照布尔谓词或其他表达式。
- 按照复合键。
此外,最后两个查询将它们的结果投影到一个新的匿名类型中,该类型仅包含学生的名字和姓氏。
//单个属性作为组键对源元素进行分组
var queryLastNames =
from student in students
group student by student.LastName into newGroup
orderby newGroup.Key
select newGroup; 通过使用除对象属性以外的某个项作为组键对源元素进行分组, 在此示例中,键是学生姓氏的第一个字母
var queryFirstLetters =
from student in students
group student by student.LastName[]; /*
通过使用某个数值范围作为组键对源元素进行分组。 然后,查询将结果投影到一个匿名类型中,该类型仅包含学生的名字和姓氏以及该学生所属的百分点范围。 使用匿名类型的原因是没有必要使用完整的 Student 对象来显示结果。*/
Helper method, used in GroupByRange.
protected static int GetPercentile(Student s)
{
double avg = s.ExamScores.Average();
return avg > ? (int)avg / : ;
} var queryNumericRange =
from student in students
let percentile = GetPercentile(student)
group new { student.FirstName, student.LastName } by percentile into percentGroup
orderby percentGroup.Key
select percentGroup; //通过使用布尔比较表达式对源元素进行分组
var queryGroupByAverages = from student in students
group new { student.FirstName, student.LastName }
by student.ExamScores.Average() > into studentGroup
select studentGroup; /*
下面的示例演示如何使用匿名类型来封装包含多个值的键。 在此示例中,第一个键值是学生姓氏的第一个字母。 第二个键值是一个布尔值,它指定该学生在第一次考试中的得分是否超过了 85。 可以按照该键中的任何属性对多组值进行排序。*/
var queryHighScoreGroups =
from student in students
group student by new { FirstLetter = student.LastName[],
Score = student.ExamScores[] > } into studentGroup
orderby studentGroup.Key.FirstLetter
select studentGroup;
创建嵌套分组
public void QueryNestedGroups()
{
var queryNestedGroups =
from student in students
group student by student.Year into newGroup1
from newGroup2 in
(from student in newGroup1
group student by student.LastName)
group newGroup2 by newGroup1.Key; // Three nested foreach loops are required to iterate
// over all elements of a grouped group. Hover the mouse
// cursor over the iteration variables to see their actual type.
foreach (var outerGroup in queryNestedGroups)
{
Console.WriteLine("DataClass.Student Level = {0}", outerGroup.Key);
foreach (var innerGroup in outerGroup)
{
Console.WriteLine("\tNames that begin with: {0}", innerGroup.Key);
foreach (var innerGroupElement in innerGroup)
{
Console.WriteLine("\t\t{0} {1}", innerGroupElement.LastName, innerGroupElement.FirstName);
}
}
}
}
分组数据类型IGrouping接口:
namespace System.Linq
{
public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable
{
TKey Key { get; }
} public interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable
{
IEnumerable<TElement> this[TKey key] { get; }
int Count { get; }
bool Contains(TKey key);
}
}
对分组操作执行子查询
创建一个查询,以便将源数据排序到不同的组中,然后分别对每个组执行子查询。
每个示例中的基本技术都是使用一个名为 studentGroup 的“延续”对源元素进行分组,然后生成一个针对 studentGroup的新的子查询。 此子查询是针对外部查询所创建的每个新组运行的。
请注意,在此特定示例中,最终的输出不是组,而是匿名类型的平面序列,代码如下:
public void QueryMax()
{
var queryGroupMax =
from student in students
group student by student.Year into studentGroup
select new
{
Level = studentGroup.Key,
HighestScore =
(from student2 in studentGroup
select student2.ExamScores.Average()).Max()
}; int count = queryGroupMax.Count();
Console.WriteLine("Number of groups = {0}", count); foreach (var item in queryGroupMax)
{
Console.WriteLine(" {0} Highest Score={1}", item.Level, item.HighestScore);
}
}
参考
[1]MSDN,对查询结果进行分组
LINQ查询表达式(3) - LINQ 查询分组的更多相关文章
- 十五、C# 使用查询表达式的LINQ
使用查询表达式的LINQ 本章介绍了一种新的语法,查询表达式. 1.查询表达式概述 2.特点:投射 筛选 排序 Let 分组 3.作为方法调用 标准查询运算符所实现的查询在功能上 ...
- 查询表达式和LINQ to Objects
查询表达式实际上是由编译器“预处理”为“普通”的C#代码,接着以完全普通的方式进行编译.这种巧妙的发式将查询集合到了语言中,而无须把语义改得乱七八糟 LINQ的介绍 LINQ中的基础概念 降低两种数据 ...
- C#复习笔记(4)--C#3:革新写代码的方式(查询表达式和LINQ to object(下))
查询表达式和LINQ to object(下) 接下来我们要研究的大部分都会涉及到透明标识符 let子句和透明标识符 let子句不过是引入了一个新的范围变量.他的值是基于其他范围变量的.let 标识符 ...
- 《C#本质论》读书笔记(15)使用查询表达式的LINQ
15.1 查询表达式的概念 简单的查询表达式 private static void ShowContextualKeywords1() { IEnumerable<string> sel ...
- LINQ 查询表达式(C# 编程指南)
语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上. 借助于 LINQ,查询现在 ...
- LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树
序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...
- Linq之查询表达式语法详解
1.闲言碎语 由于项目的需要接触到Linq,刚开始有些不适应,好多概念都很模糊.不过经过一段时间的摸索,慢慢地对Linq有了一个更加深入的了解.在此记录一下备忘. 2.查询表达式语法 执行L ...
- 2.1 LINQ的查询表达式
在进行LINQ查询的编写之前,首先需要了解查询表达式.查询表达式是LINQ查询的基础,也是最常用的编写LINQ查询的方法. 查询表达式由查询关键字和对应的操作数组成的表达式整体.其中,查询关键字是常用 ...
- LINQ查询表达式基础
LINQ,语言集成查询(Language Integrated Query)是一组用C#和Visual Basic语言的扩展. 对于编写查询的开发人员来说,LINQ 最明显的"语言集成&qu ...
- 认识LINQ的第一步---从查询表达式开始
学习和使用C#已经有2个月了,在这两个月的学习中,深刻体会到,C#这门语言还真不适合编程初学者学习,因为它是吸取了很多其他语言,不仅是面向对象,还包括函数式语言的很多特性,导致它变成特性大爆炸的语言. ...
随机推荐
- saltstack配置文件详解
软件依赖 Python版本大于2.6或版本小于3.0: 对Python版本要求 msgpack-python: SalStack消息交换库 YAML: SaltStack配置解析定义语法 Jinja2 ...
- [转帖]中兴GoldenDB数据库开始了第一轮中信银行核心业务系统迁移落地
中兴GoldenDB数据库开始了第一轮中信银行核心业务系统迁移落地 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https:// ...
- 函数的练习1——python编程从入门到实践
8-1 消息: 编写一个名为display_message()的函数,它打印一个句子指出你在本章学的是什么.调用这个函数,确认显示的消息正确无误. def display_message(): pri ...
- day45——html常用标签、head内常用标签
day45 MySQL内容回顾 数据库 DBMS mysql -RDBMS 关系型 数据库分类 关系型:mysql\oracle\sqlserver\access 非关系型:redis,mongodb ...
- Magic Line(思维+计算几何问题)(2019牛客暑期多校训练营(第三场))
示例: 输入: 140 1-1 01 00 -1 输出:-1 999000000 1 -999000001 题意:给定平面上一系列的点,求一条以(x1,y1),(x2,y2)两点表示的直线将平面分为包 ...
- Linux -- touch 命令
在Linux中,每个文件都关联一个时间戳,并且每个文件搜会存储最近一次访问的时间.最近一次修改的时间和最近一次变更的时间等信息.所以,无论何时我们创建一个新文件,访问或者修改一个已经存在的文件,文件的 ...
- AS3放大镜工具类
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Display ...
- [LOJ2537] [PKUWC2018] Minimax
题目链接 LOJ:https://loj.ac/problem/2537 洛谷:https://www.luogu.org/problemnew/show/P5298 Solution 不定期诈尸 好 ...
- [LOJ#3119][Luogu5400][CTS2019]随机立方体(容斥+DP)
https://www.cnblogs.com/cjyyb/p/10900993.html #include<cstdio> #include<algorithm> #defi ...
- 【转载】C#中string类使用Remove方法来移除指定位置的字符
在C#的字符串操作过程中,有时候需要将字符串中指定位置的字符移除,此时就可能使用到字符串类string类中的Remove方法,此方法允许指定移除开始的开始的索引位置,以及移除的长度信息等,共有2个重载 ...