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

ASP.NET
使用函数传递参数来执行相应的数据库操作
如何实现在窗体和窗体之间进行传递数据
ASP.NET中文显示之两种解决方法
ASP.NET、JSP及PHP之间的抉择
ASP.NET 2.0发送电子邮件中存在的问题
谈谈HtmlControl与WebControl的区别与用途
从ASP.NET 1.1升级到ASP.NET 2.0要考虑的Cookie问题
通过系统配置来提高ASP.NET应用程序的稳定性
妙用ASP2.0中的URL映射改变网址
AJAX实现web页面中级联菜单的设计
ASP.NET跨页面传值技巧总结
再议ASP.NET DataGrid控件中的“添加新行”功能
Geometry 对象浅析
重构CollapsibleSplitter
如何利用.NET Framework使用RSS feed
ASP.NET获取IP与MAC地址的方法
在ASP.NET 2.0中使用样式、主题和皮肤
ASP.NET中为GridView添加删除提示框
ASP.NET 2.0,无刷新页面新境界
看看一个.net版对话框控件

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


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