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

ASP.NET
asp.net Server.MapPath方法注意事项
asp.net下常用的加密算法MD5、SHA-1应用代码
几个 ASP.NET 小技巧
ASP.NET内置对象之Application对象
ASP.NET使用正则表达式屏蔽垃圾信息
asp.net“服务器应用程序不可用” 解决方法
asp.net Linq把数据导出到Excel的代码
asp.net ext treepanel 动态加载XML的实现方法
silverlight2.0Beta版TextBox输入中文解决方法
asp.net转出json格式客户端显示时间
asp.net下Linq To Sql注意事项小结
ASP.NET动态加载用户控件的实现方法
asp.net web大文件上传带进度条实例代码
asp.net DZ论坛中根据IP地址取得所在地的代码
向asp.Net进发 数据库连接操作
.net 上传文件前所未有的简单
asp.net gridview代码绑定
asp.net中List的使用方法
Asp.net(C#)实现验证码功能代码
asp.NET开发中正则表达式中BUG分析

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 294 ::
收藏到网摘: 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()

 

待续!