Ordering方法实现Linq排序

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

Linq排序方法有多种,本文只介绍Linq排序Ordering方法,要想轻轻松松的学习Linq排序是很容易实现的,但是要仔细读此文章哦!

主要方法:

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

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

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

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

OrderBy, OrderByDescending参数:

输入序列: IEnumerable

主键选择器: TSource => TKey

返回类型是IOrderedEnumerable

ThenBy, ThenByDescending参数:

输入序列: IOrderedEnumerable

主键选择器:TSource => TKey

简要介绍:

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

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

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

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

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

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

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

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

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

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

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

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

复合语法为:

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

Comparers和Collations

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

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

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

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

IOrderedEnumerable与IOrderedQueryable

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

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

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

  1. IOrderedEnumerable<string> query1 = ames.OrderBy (s => s.Length);   
  2.  OrderedEnumerable<string> query2 =uery1.ThenBy (s => s); 

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

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

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

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

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

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

对于解释性查询, 与之对应的是调用AsQueryable()。

以上就是对Linq排序方法的简单介绍。

【编辑推荐】

  1. 为你揭晓 Linq更新数据是否真的实用?
  2. 深度剖析linq级联删除
  3. 简单实现Linq连接查询
  4. LINQ动态查询的实现浅析
  5. 简单实现Linq多条件查询
责任编辑:阡陌 来源: IT粉丝网 
相关推荐

2009-09-17 08:47:00

Linq插入数据

2009-09-17 11:32:52

LINQ调用存储过程

2009-09-17 13:10:48

linq动态排序

2009-12-23 09:04:41

LINQ通用分页

2009-08-27 13:10:54

LINQ from子句

2009-09-14 10:45:33

LINQ删除数据

2009-09-09 13:18:26

Linq Submit

2009-09-14 16:41:23

LINQ To XML

2009-09-09 09:59:08

Linq调用LoadP

2009-09-15 17:15:33

Linq排序

2009-09-16 17:07:00

linq实现Left

2009-09-11 10:20:36

Linq扩展方法

2009-09-17 11:29:50

Linq扩展方法

2009-05-11 10:40:36

.NETLINQforeach

2009-09-10 16:32:19

LINQ Where

2009-09-08 15:39:13

Linq使用Inser

2009-09-15 16:26:46

Linq排序

2009-09-17 09:24:57

Linq实现分页

2009-09-08 16:55:01

Linq实现XML转换

2009-09-14 18:23:59

LINQ嵌套查询
点赞
收藏

51CTO技术栈公众号