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

ASP.NET
不同映射模式下的直线输出的效果问题
ASP.NET开发下的MVC设计模式的实现
ASP.NET编写应用程序的十大技巧
ASP.NET中使用AJAX的简单方法
ASP.NET MVC实现自己的视图引擎
认识asp.net会话状态
ASP.NET实现页面传值的几种方法
.NET中容易混淆的几组重要概念
详解.NET中的动态编译技术
如何使用ASP.Net加密Cookie
ASP.NET 2.0跨网页提交的三种方法
ASP.NET 2.0创建母版页引来的麻烦
.Net整合其他平台的一些探讨
ASP.NET编程经验技巧10则
最佳实践 ADO.NET实用经验无保留曝光
在.NET上执行多线程操作要考虑的两大因素
.Net开发 细说Visual Basic.Net
ASP.NET网络编程中经常用到的27个函数集
ASP.NET防止用户多次登录的方法
对ASP.NET MVC项目中的视图做单元测试

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


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