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

ASP.NET
FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用方法
.NET 常用功能和代码小结
在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出
asp.net IList查询数据后格式化数据再绑定控件
asp.net sql存储过程
asp.net 简单实现禁用或启用页面中的某一类型的控件
asp.net(c#)获取内容第一张图片地址的函数
The remote procedure call failed and did not execute的解决办法
ASP.NET 在线文件管理
asp.net 读取并修改config文件实现代码
ASP.NET Cookie 操作实现
asp.net Silverlight中的模式窗体
Silverlight中动态获取Web Service地址
asp.net Silverlight应用程序中获取载体aspx页面参数
asp.net 水晶报表隔行换色实现方法
asp.net 获取Gridview隐藏列的值
手动把asp.net的类生成dll文件的方法
asp.net 使用ObjectDataSource控件在ASP.NET中实现Ajax真分页
动态指定任意类型的ObjectDataSource对象的查询参数
asp.net Md5的用法小结

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


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

 

待续!