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

ASP.NET
asp.net GridView控件中模板列CheckBox全选、反选、取消
asp.net GridView 删除时弹出确认对话框(包括内容提示)
asp.net DropDownList 三级联动下拉菜单实现代码
asp DataTable添加列和行的三种方法
Asp.net 页面调用javascript变量的值
asp.net 长文章通过设定的行数分页
asp.net 定时间点执行任务的简易解决办法
asp.net 页面延时五秒,跳转到另外的页面
asp.net 动态输出透明gif图片
asp.net DataList与Repeater用法区别
asp.net Javascript获取CheckBoxList的value
asp.net程序在调式和发布之间图片路径问题的解决方法
asp.net下生成英文字符数字验证码的代码
asp.net 页面版文本框智能提示JSCode (升级版)
ASP.NET URL伪静态重写实现方法
ASP.NET 2.0 中Forms安全认证
asp.net 动态添加多个用户控件
asp.net Repeater显示父子表数据,无闪烁
asp.net 无法获取的内部内容,因为该内容不是文本 的解决方法
asp.net GridView排序简单实现

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


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

 

待续!