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

ASP.NET
赫赫大名的A*寻路算法(vb.net版本)
asp.net(c#)下Jmai去说明 使用与下载
[原创]完美解决Could not load file or assembly ''AjaxPro.2'' or one of its dependencies. 拒绝访问。
asp.net下gridview 批量删除的实现方法
用CSS实现图片倾斜 只支持IE
.net get set用法小结
vs 不显示行号的操作方法
ASP.NET页面进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
ASP.Net不执行问题一解
asp.net 无限分类
让VS2008对JQuery语法的智能感知更完美一点
扩展方法ToJSON() and ParseJSON()
asp.net下PageMethods使用技巧
Linq to SQL Delete时遇到问题的解决方法
实现ASP.NET多文件上传程序代码
ASP.NET AJAX 1.0 RC开发10分钟图解
asp.net get set用法
ASP.NET下使用WScript.Shell执行命令
asp.net2.0实现邮件发送(测试成功)
Asp.net 无限级分类实例代码

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


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

 

待续!