当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > LINQ学习笔记:分组Grouping

ASP.NET
一个无刷新效果定时自动更新页面的例子
ASP.NET2.0的控件状态和视图状态探讨
用好ASP.NET 2.0的URL映射
详解:如何在.NET中访问MySQL数据库?
如何实现Asp与Asp.Net共享Session
利用.net的强大功能发送email
.NET中加密与解密QueryString的方法
Asp.net生成htm静态文件的两种途径
C#定时器的使用
从XML文件中读取数据绑定到DropDownList
ASP.NET 2.0 里输出文本格式流
用.net动态创建类的实例
.Net下的MSMQ的同步异步调用
ASP.NET 2.0实现防止同一用户同时登陆
asp.NET自定义服务器控件内部细节
组合.NET数据控件构建强大用户接口
用ASP.NET 2.0 FormView控件控制显示
菜鸟也学习ASP.NET如何读取数据库内容
教你简单方便获取Web设计的免费资源
专家详解:复杂表达式的执行步骤

ASP.NET 中的 LINQ学习笔记:分组Grouping


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 79 ::
收藏到网摘: n/a

分组Grouping

主要方法:

GroupBy: 将一个序列分组插入一个子序列, 对应SQL语法是GROUP BY

主要参数:

输入序列: IEnumerable

主键选择器: TSource => TKey

元素选择器(可选): TSource => TElement

比较器(可选):IEqualityComperar

返回类型是IEnumerable>

简要介绍

GroupBy将一个扁平的输入序列转换成一组序列, 例如,以下示例通过文件扩展名将c:\temp下面的文件分组:

 1: string[] files = Directory.GetFiles(“c:\\temp”);
 2:  
 3: IEnumerable<string,string>> query =
 4:  
 5: files.GroupBy(file => Path.GetExtension(file));

 

或者,你可以使用隐式类型减少代码输入:

 1: var query = files.GroupBy(file => Path.GetExtension(file));

 

枚举返回结果:

 1: foreach (IGrouping<string,string>grouping in query)
 2:  
 3: {
 4:  
 5: Console.WriteLine(“Extension: “ + grouping.Key);
 6:  
 7: foreach (string filename in grouping)
 8:  
 9: Console.WriteLine (” - “ + filename);
 10:  
 11: }

 

Enumerable.GroupBy将输入元素读入临时的目录字典,所有拥有相同key的元素都会被归入相同的二级目录. 默认情况下, 每一个grouping的元素都是未转换的输入元素, 除非你提供了一个elementSelector参数. 以下查询将每一个元素都转换为大写:

 1: files.GroupBy (file =>
 2:  
 3: ath.GetExtension (file), file => file.ToUpper());

 

elementSelector和keySelector是独立的,因此此查询将会得到与上面一样的分组结果.

另外,所有的子序列并不会根据字母排序,它只做分组, 而没有做任何排序相关的工作, 只是简单保存了原有序列排列的顺序. 如果你要排序, 必须要显式调用OrderBy操作符:

 1: string[] files = Directory.GetFiles(“c:\\temp”);
 2:  
 3: files.GroupBy (file => Path.GetExtension(file), file => file.ToUpper())
 4:  
 5: .OrderBy (grouping => grouping.Key);

 

如果使用复合查询语法:

 1: from file in files
 2:  
 3: group file.ToUpper() by Path.GetExtension(file);

 

与select类似, group结束一个查询语句,除非你使用”延续查询”语句:

 1: from file in files
 2:  
 3: group file.ToUpper() by Path.GetExtension(file)
 4:  
 5: into grouping
 6:  
 7: orderby grouping.Key
 8:  
 9: select grouping;

 

延续查询通常在group by查询中是很有用的,以下示例显示那些文件总数小于5的分组目录:

 1: from file in files
 2:  
 3: group file. ToUpper()by Path.GetExtension (file)
 4:  
 5: into grouping
 6:  
 7: where grouping.Count() < 5
 8:  
 9: select grouping;

 

有些时候你可能只需要得到一个组的聚合结果,因此你可以丢弃子序列:

 1: string[] votes = {“Bush”,“Gore”,“Gore”,“Bush”,“Bush” };
 2:  
 3: IEnumerable<string> query = from vote in votes
 4:  
 5: group vote by vote into g
 6:  
 7: orderby g.Count() descending
 8:  
 9: select g.Key;
 10:  
 11: string winner = query.First(); // Bush

 

LINQ to SQL当中的GroupBy

Grouping在解释性查询中的工作方式与上述是一样的. 当然, 如果你在LINQ to SQL实体当中有关联属性, 你会发现需要使用group的时候比在标准SQL当中要少很多.例如, 要找到那些采购订单不少于两个的客户, 我们并不需要group, 以下示例就可以了:

 1: from c in dataContext.Customers
 2:  
 3: where c.Purchases.Count >= 2
 4:  
 5: select c.Name + ” has made “ + c.Purchases.Count
 6:  
 7: + ” purchases”;

 

另外一个你可能需要分组的例子是计算年度收入:

 1: from p in dataContext.Purchases
 2:  
 3: group p.Price by p.Date.Year into salesByYear
 4:  
 5: select new {
 6:  
 7: Year = salesByYear.Key,
 8:  
 9: TotalValue = salesByYear.Sum()
 10:  
 11: };

 

多主键分组

我们可以使用一个匿名类型根据一个符合主键进行分组

 1: from n in names
 2:  
 3: group n by new { FirstLetter = n[0], Length = n.Length };

 

自定义Comparer

对于本地查询,你可以传递一个自定义的comparer到GroupBy中改变默认的主键比较算法.虽然这种需求是极少的,因为通常改变keySelector就足够了.以下示例创建不区分大小写的分组:

 1: group name by name.ToUpper()

 

待续!