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

ASP.NET
赫赫大名的A*寻路算法(vb.net版本)
asp.net(c#)下Jmai去说明 使用与下载
[原创]完美解决Could not load file or assembly ''AjaxPro.2'' or one of its dependencies. 拒绝访问。
asp.net下gridview 批量删除的实现方法
用CSS实现图片倾斜 只支持IE
.net get set用法小结
vs 不显示行号的操作方法
ASP.NET页面进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
ASP.Net不执行问题一解
asp.net 无限分类
让VS2008对JQuery语法的智能感知更完美一点
扩展方法ToJSON() and ParseJSON()
asp.net下PageMethods使用技巧
Linq to SQL Delete时遇到问题的解决方法
实现ASP.NET多文件上传程序代码
ASP.NET AJAX 1.0 RC开发10分钟图解
asp.net get set用法
ASP.NET下使用WScript.Shell执行命令
asp.net2.0实现邮件发送(测试成功)
Asp.net 无限级分类实例代码

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


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