对查询结果进行分组

  分组是 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,对查询结果进行分组

最新文章

  1. php 封装 知识点
  2. Command Pattern
  3. WIN7 WIN8 WIN10你们的WmiPrvSE.exe系统占用资源厉害吗?
  4. C++ 非阻塞套接字的使用 (3)
  5. #pragma pack(n)
  6. ant导入Zookeeper到Eclipse错误path contains invalid character
  7. Djang DJANGO_SETTINGS_MODULE
  8. 【自学php】第四天 - 使用数组
  9. MYSQL正在使用select发现现场记录方法,包括一个逗号分隔的字符串
  10. C/C++生成随机数
  11. SQL两列数据,行转列
  12. linux下安装PHP扩展memcache
  13. [转]node-sass 安装失败的各种坑
  14. oracle sql优化的几种方法
  15. 第一行代码 -3-2 软件也要拼脸蛋-UI界面-更强大的滚动条-RecyclerView
  16. np.split()和np.array_split()
  17. Git常见使用方法
  18. golang 创建一个简单的连接池,减少频繁的创建与关闭
  19. DIOCP3-DIOCP1升级到DIOCP3
  20. 全栈JavaScript之路(十三)了解 ElementTraversal 规范

热门文章

  1. keystone 域中项目、用户、角色的创建
  2. ll问题
  3. 小白都能看懂的vue中各种通信传值方式,附带详细代码
  4. 12 Spring JdbcTemplate的使用
  5. Java开发笔记(一百二十五)AWT图像加工
  6. php中的__get和__set方法
  7. 47 容器(六)——HashMap
  8. flask框架(一)——初识Flask
  9. MVC与MTV模型
  10. prometheus grafana graylog 钉钉告警 短信告警 电话告警系统 PrometheusAlert