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

ASP.NET
二级域名Cookie问题的解决方法
如何为asp.net网站项目添加子项目
asp.net用url重写URLReWriter实现任意二级域名
asp.net 序列化and反序列化演示
asp.net Timer的使用方法
AjaxControlToolKit DropDownExtender(下拉扩展控件)使用方法
AjaxControlToolKit CalendarExtender(日历扩展控件)的使用方法
让GridView只显示特定用户的数据的方法
让GridView只更新某些特定的数据的方法
ajaxControlToolkit中CascadingDropDown的用法说明
axp.net ScriptManager的简单用法
把程序集安装到全局程序集缓存中的步骤
引用全局程序集缓存内的程序集的方法
asp.net COOKIES需要注意的一点
asp.net UrlReWriter使用经验小结
页面导出为Excel的时间格式的问题
asp.net cookie清除的代码
Asp.net XMLHTTP封装类(GET,Post发送和接收数据)
ASP.NET XmlHttp跨域访问实现代码
Asp.NET 随机码生成基类(随机字母,随机数字,随机字母+数字)

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


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