当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > LINQ学习笔记:聚合方法

ASP.NET
Asp.net利用JQuery弹出层加载数据代码
asp.net dataview做无限极分类的又一用法
asp.net ckeditor编辑器的使用方法
告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)
asp.net 实现动态显示当前时间(不用javascript不考虑开销)
.net动态显示当前时间(客户端javascript)
asp.net 结合YUI 3.0小示例
asp.net 取消缓存相关问题说明
asp.net 计划任务管理程序实现,多线程任务加载
ASP.NET 跨页面传值方法
asp.net中url地址传送中文参数时的两种解决方案
Asp.net 菜单控件简洁版
asp.net jQuery Ajax用户登录功能的实现
asp.net SharpZipLib的压缩与解压问题
asp.net url重写后页面回传问题
asp.net与Discuz!NT整合集成实例教程
Discuz!NT 3与asp.net 整合的实例教程
测试控制台使用方法
.net 动态标题实现方法
asp.net *.ashx类型的文件使用说明

ASP.NET 中的 LINQ学习笔记:聚合方法


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

聚合方法

主要方法:

Count, LongCount: 返回输入序列的元素数量, 并且满足一个断言(可选), SQL对应语法为COUNT()

Min, Max: 返回输入序列中的最小或最大的元素, SQL对应语法为MIN(), MAX()

Sum, Average: 计算序列中的所有元素的总和或者平均数, SQL对应语法为SUM(), AVG()

Aggregate: 执行一个自定义的聚合计算, 无对应SQL语法

Count, LongCount

源序列: IEnumerable

断言: TSource => bool (可选)

Count枚举一个序列并返回其中的元素总数:

 1: int fullCount = new int[] { 5, 6, 7}.Count(); // 3

 

在IEnumerable.Count的内部实现中, 它首先测试输入序列是否实现了ICollection, 如果是, 则直接调用ICollection.Count, 否则就利用一个简单的计算数遍历所有元素每次加1获得最后的总数.

另外, 我们也可以在查询中提供一个断言:

 1: int digitCount = “jame921″.Count (c => char.IsDigit (c)); // 3

 

LongCount跟Count做一样的工作, 只不过它返回的是一个64位的整数, 可以计算超过20亿的元素

Min和Max

源序列: IEnumerable

可选结果选择器: TSource => TResult

Min和Max分别返回输入序列中最小和最大的元素:

 1: int[] numbers = { 28, 32, 14 };
 2:  
 3: int smallest = numbers.Min(); // 14;
 4:  
 5: int largest = numbers.Max(); // 32;

 

你也可以包含一个选择表达式:

 1: int smallest = numbers.Max (n => n % 10); // 8;

 

如果元素本身并不是可比较的, 那么选择器表达式就是必须的了, 换句话说, 如果元素没有实现IComparable, 例如:

 1: Purchase runtimeError =
 2:  
 3: dataContext.Purchases.Min(); // 编译错误
 4:  
 5: decimal? lowestPrice =
 6:  
 7: dataContext.Purchases.Min (p => p.Price); // OK

 

一个选择器表达式不仅决定元素之间如何做比较, 同时也可以影响最后的结果. 例如前面的例子返回的结果是一个decimal类型的数值, 而不是一个purchase对象, 为了要获得最便宜的采购订单, 我们需要一个子查询:

 1: Purchase cheapest = dataContext.Purchases
 2:  
 3: .Where (p => p.Price ==
 4:  
 5: dataContext.Purchases.Min(p2 => p2.Price))
 6:  
 7: .FirstOrDefault();

 

Sum与Average

源序列: IEnumerable

可选的结果选择器: TSource => TResult

Sum和Average这两个聚合操作符使用与Min和Max类似:

 1: decimal[] numbers = { 3, 4, 8 };
 2:  
 3: decimal sumTotal = numbers.Sum(); // 15
 4:  
 5: average = numbers.Average(); // 5

 

以下查询返回names数组中每一个元素的长度总和:

 1: int combinedLength = names.Sum (s =>s.Length);

 

Sum和Average操作必需是关于数值类型(int, long, float, double以及nullable版本), 相反的, Min和Max就没有这么严格的限定, 它们可以操作那些实现了Icomparable的元素, 例如string. 此外, Average总是返回decimal或者double两者之一:

1.如果选择器类型是decimal,则返回类型也是decimal

2.如果选择器类型是int, long, float, double, 则返回类型是double

这意味着下面的查询无法编译(因为double不能为自动转换为int)

 1: int avg = new int[] { 3, 4 }.Average();

 

但是以下的查询则没有问题:

 1: double avg = new int[] { 3, 4}.Average(); // 3.5

 

Average隐式提高输入值的精度以避免原有精度丢失. 这这个例子中, 我们取得平均值3.5, 而不需要去诉求于一个输入元素的转换:

 1: double avg = numbers.Average (n =>(double) n);

 

在LINQ to SQL中, Sum和Average被翻译成了标准的SQL聚合函数, 以下的查询返回了那些包含有订单平均值 > 500的客户名称:

 1: from c in dataContext.Customers
 2:  
 3: where c.Purchases.Average (p => p.Price) > 500
 4:  
 5: select c.Name;

 

聚合

Aggregate允许你嵌入一个自定义的算法来实现那些不是很常用的聚合场景. Aggregations在LINQ to SQL当中不受支持. 以下的查询演示了如果使用Aggregate来做与Sum的工作:

 1: int[] numbers = { 1, 2, 3 };
 2: int sum = numbers.Aggregate (0, (seed, n)=> seed + n);

 

  第一个参数是seed,表示从那个元素位置开始计算. 第二个参数是一个更新计算结果值的表达式, 并作为一个新的元素继续循环下去. 我们还可以使用可选的第三个参数在返回值的时候再作进一步的project. 待续!