当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > LINQ学习笔记:排序Ordering

ASP.NET
Internet Explorer 编程简述(二)在IE中编辑OLE嵌入文档
移动窗体
.NET 2.0获取数据库连接统计数据
VB.NET 拖动无边框的窗体
利用WH_CBT Hook将非模态对话框显示为模态对话框
Aspect#应用 - 权限验证
VB 从零开始编外挂(一)
【错误解决】Unable to find script library 'WebUIValidation.js'
VB 从零开始编外挂(四)
DTD指南(3)-DTD-Elements(元素)
知识库文章MDL9745154-File:Microsoft Visual Basic 运行时库
.net手机软件开发(六)OBEX应用:文件传输部分
在winform中使用WebBrowser控件时怎样去除IE的滚动条
WINZIP及WINRAR命令!!!!!
智能客户端相关Application Block结构功能分析(二)
如何在VB中操作EXCEL(一段代码,两个可以使用的过程)
在C#中用最简洁有效的代码执行存储过程并返回数据
.Net的Collection类的一些使用说明
ASP.NET实现数据图表c
用asp.net画饼图

ASP.NET 中的 LINQ学习笔记:排序Ordering


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

排序Ordering

主要方法:

OrderBy, ThenBy: 正序排列输入序列, SQL对应语法为ORDER BY

OrderByDescending, ThenByDescending: 倒序排列输入序列, SQL对应语法为ORDER BY … DESC

Reverse: 反转输入序列, 无SQL对应语法

排序操作符返回不同顺序但与输入序列相同的元素

OrderBy, OrderByDescending参数:

输入序列: IEnumerable

主键选择器: TSource => TKey

返回类型是IOrderedEnumerable

ThenBy, ThenByDescending参数:

输入序列: IOrderedEnumerable

主键选择器:TSource => TKey

简要介绍:

OrderBy返回输入序列的一个排序版本, 其使用keySelector表达式作比较. 以下的例子返回了按字母排序的名字列表:

 1: IEnumerable<string> query = names.OrderBy(n => n);

 

此例子则是按名字长度排序:

 1: IEnumerable<string> query = names.OrderBy (n => n.Length);

 

如果元素具有相同的排序键那么它们的顺序可能是不确定的 – 除非你增加一个ThenBy操作符:

 1: string[] names = {“James”, “Jack”, “Todd”, “David”, “Kobe”};
 2:  
 3: IEnumerable<string> query = names.OrderBy (n => n.Length)
 4:  
 5: .ThenBy (n => n);
 6:  
 7: //{Jack,Todd,Kobe,James,David}

 

ThenBy只会重新排列那些拥有同样排序键的元素.你可以串联任意多个ThenBy操作符,如下示例:

 1: IEnumerable<string> query = names.OrderBy (s => s.Length)
 2:  
 3: ThenBy (s => s[1]).ThenBy (s => s[0]);

 

先按名字长度排序, 再按第2个字符排序, 最后再按第1个字符排序, 其对应的复合查询为:

 1: IEnumerable<string> query = from s in names
 2:  
 3: rderby s.Length, s[1], s[0]
 4:  
 5: elect s;

 

LINQ另外也提供了OrderByDescending和ThenByDescending操作符,生成一个倒序的结果集,以下的LINQ to SQL的示例表示按照价格倒序再按描述的字母顺序排列:

 1: dataContext.Purchases.OrderByDescending(p => p.Price)
 2:  
 3: .ThenBy (p =>p.Description);

 

复合语法为:

 1: from p in dataContext.Purchases
 2:  
 3: orderby p.Price descending, p.Description
 4:  
 5: select p;

 

Comparers和Collations

在本地查询中, 键选择器本身会通过他们默认的IComparable实现来决定排序算法. 我们可以通过提供一个IComparer对象来覆盖默认的排序算法, 以下示例表示要执行一个大小写无关的排序:

 1: names.OrderBy (n => n, StringComparer.CurrentCultureIgnoreCase);

 

在复合查询中不支持传递Comparer,同样LINQ to SQL当中也不支持. 在LINQ to SQL当中, 比较算法是由对应列的collation决定的. 如果collation是大小写敏感的,你可以通过在键选择器中调用ToUpper来完成非大小写敏感的排序:

 1: from p in dataContext.Purchases
 2:  
 3: orderby p.Description. ToUpper()
 4:  
 5: select p;

 

IOrderedEnumerable与IOrderedQueryable

排序操作符返回了特殊的IEnumerable子类, 如果是Enumerable那么则对应是IOrderedEnumerable,如果是Queryable,则返回的是IOrderedQueryable类. 这些子类型允许使用一个后来的ThenBy操作符继续提炼而不是代替之前的排列顺序.

这些子类型定义的成员并非公开暴露的, 因此他们看起来像是原始序列.

但实际上他们是不同类型, 当我们渐进创建查询的时候就可以发现:

 1: IOrderedEnumerable<string> query1 =
 2:  
 3: ames.OrderBy (s => s.Length);
 4:  
 5: OrderedEnumerable<string> query2 =
 6:  
 7: uery1.ThenBy (s => s);

 

如果我们使用IEnumerable带来query1现有的生命,那么第二行将无法编译—ThenBy需要一个IOrderedEnumerable类型的输入.当然, 使用var可以免去这个担心:

 1: var query1 = names.OrderBy (s =>s.Length);
 2:  
 3: var query2 = query1. ThenBy (s => s);

 

然而, 使用隐式类型可能也会有一些问题, 如下:

 1: var query = names.OrderBy (s =>s.Length);
 2:  
 3: query = query.Where (n =>n.Length > 3); //错误,无法编译

 

OrderBy输出的序列类型是IOrderedEnumerable, 然后对于下一行的Where操作来说它的输出类型是IEnumerable因此无法再次赋值给query,解决的办法是在OrderBy之后显式调用AsEnumerable():

 1: var query = names.OrderBy (s =>s.Length).AsEnumerable();
 2:  
 3: query =query.Where (n => n.Length > 3); // OK

 

对于解释性查询, 与之对应的是调用AsQueryable().待续!