在Linq中排序操作可以按照一个或多个关键字对序列进行排序。其中第一个排序关键字为主要关键字,第二个排序关键字为次要关键字。Linq排序操作共包含以下5个基本的操作。

1、OrderBy操作,根据排序关键字对序列进行升序排序

2、OrderByDescending操作,根据排序关键字对序列进行降序排序

3、ThenBy操作,对次要关键字进行升序排序

4、ThenByDescending操作,对次要关键字进行降序排序

5、Reverse操作,将序列中的元素进行反转

  那么下面我们就逐一来分析一下每个排序操作。

OrderBy操作

  OrderBy操作是按照主关键字对序列进行升序排序的操作。Enumerable类的OrderBy()原型如下:

  1. public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  2. {
  3. return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false);
  4. }
  5.  
  6. public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  7. {
  8. return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, false);
  9. }

其中source表示数据源,keySelector表示获取排序的关键字的函数,comparer参数表示排序时的比较函数。TSource表示数据源的类型,TKey表示排序关键字的类型。下面我们用两种方式来比较排序,第一种按照前面讲的查询表达式来排序,第二种用现在的排序操作来排序,其实结果都是一样的。

  1. private void OrderByQuery()
  2. {
  3. int[] ints = new int[] { , , , , , , };
  4.  
  5. //使用查询表达式来排序
  6.  
  7. Response.Write("--------------使用查询表达式来排序---------</br>");
  8. var values = from v in ints
  9.  
  10. orderby v
  11.  
  12. select v;
  13.  
  14. foreach (var item in values)
  15. {
  16.  
  17. Response.Write(item+"</br>");
  18. }
  19. //使用排序操作来排序
  20.  
  21. Response.Write("--------------使用排序操作来排序---------</br>");
  22.  
  23. var result = ints.OrderBy(x => x);
  24.  
  25. foreach (var re in result)
  26. {
  27.  
  28. Response.Write(re + "</br>");
  29. }
  30.  
  31. }

看看运行结果:

我们看到和我们预想的是一样的。那么大家可能有些疑问,为什么OrderBy是升序排序呢?

我们来从源码解析一下:

我们看到OrderBy里面最终调用了一个函数OrderedEnumerable,那么我们再来看看这个OrderedEnumerable函数:

看到这个函数有一个参数descending,我们OrderBy方法给这个参数传了false,那么就表示非降序排序,就是升序排序。可想而知,OrderByDescending操作,给这个参数传值应该是true。

第二个原型里面有个comparer参数,那么我们来看看怎么用:既然是IComparer接口类型的参数,那么我们就定义一个实现了Icomparer接口的类型:

  1. private void OrderByQuery()
  2. {
  3. int[] ints = new int[] { , , , , , , };
  4.  
  5. var result = ints.OrderBy(x => x,new CompareIntegers());
  6.  
  7. foreach (var re in result)
  8. {
  9.  
  10. Response.Write(re + "</br>");
  11. }
  12.  
  13. }
  14.  
  15. public class CompareIntegers : IComparer<int>
  16. {
  17. public int Compare(int i1, int i2)
  18. {
  19. return -*(i1 - i2);
  20. }
  21. }

我们看到,我们定义的CompareIntegers类的比较参数是,该元素取反,所以排序结果应该就成了降序排序了。我们看看测试结果:

嗯和我们预想的一样,这个comparer函数就是我们自定义的比较方式。

OrderByDescending操作

  OrderByDescending和我们上面的OrderBy操作相似,最终都是调用OrderedEnumerable只是传入的descending参数的值不同。看看OrderByDescending的原型:

  1. public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
  2.  
  3. public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);

也有两个原型,跟OrderBy的原型一模一样,只是最终调用OrderedEnumerable方法的传入参数不同。

我们看到这个传入的是true,表示降序排列。所以我个人觉得这两个操作可以合并,然后多一个参数而已。

同样写个例子测试一下:

  1. private void OrderByDescendingQuery()
  2. {
  3. int[] ints = new int[] { , , , , , , };
  4.  
  5. //使用查询表达式来排序
  6.  
  7. Response.Write("--------------使用查询表达式来排序---------</br>");
  8. var values = from v in ints
  9.  
  10. orderby v descending
  11.  
  12. select v;
  13.  
  14. foreach (var item in values)
  15. {
  16.  
  17. Response.Write(item+"</br>");
  18. }
  19. //使用排序操作来排序
  20.  
  21. Response.Write("--------------使用排序操作来排序---------</br>");
  22.  
  23. var result = ints.OrderByDescending(x => x);
  24.  
  25. foreach (var re in result)
  26. {
  27.  
  28. Response.Write(re + "</br>");
  29. }
  30.  
  31. }

看看测试结果:

嗯结果和预想的一样。

ThenBy操作

  上面两个排序都是按照主关键字来排序的,下面呢我们就看看什么是按照次要关键字排序。ThenBy 和OrderBy一样是按照升序排序的。来看看原型:

  1. public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector);
  2. public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);

原型和OrderBy一样。但是ThenBy必须要和OrderBy配合使用。就是 必须要先有OrderBy排序,然后再用ThenBy排序。不能够直接用ThenBy排序。
同样我们写个例子一看便知。这个例子呢我们每个序列的每个元素至少要有两个字段,一个做主关键字,一个做次要关键字。我们还是用前面将的UserBaseInfo来创建例子,用ID做主关键字,username做次要关键字。

  1. private void ThenByQuery()
  2. {
  3. IList<UserBaseInfo> users = new List<UserBaseInfo>();
  4.  
  5. for (int i = ; i < ; i++)
  6. {
  7. users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
  8. }
  9.  
  10. var values = users.OrderBy(u => u.ID).ThenBy(x => x.UserName);
  11.  
  12. foreach (var u in values)
  13. {
  14. Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
  15. }
  16.  
  17. }

看看结果:

ThenByDescending操作

  这个是ThenBy的降序排序方式,和前面的用法实质是一样的,我就不详细讲解了,大家可以自己研究一下。

Reverse操作

  下面我们就来看看Reverse这个排序。这个排序呢可以说也不算是排序,因为我们知道排序无非就是升序,或者降序。这个其实就是将一个序列进行反转,里面的值如果本来没有顺序,执行这个操作之后,也不会变得有序,只是序列的元素反转。

看看reverse的原型:

  1. public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source);

测试样例:

  1. private void ReverseQuery()
  2. {
  3. IList<UserBaseInfo> users = new List<UserBaseInfo>();
  4.  
  5. for (int i = ; i < ; i++)
  6. {
  7. users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
  8. }
  9.  
  10. var values = users.Reverse();
  11.  
  12. foreach (var u in values)
  13. {
  14. Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
  15. }
  16.  
  17. }

运行结果:

看确实是反转了。

  再看一个本来无序的例子。

  1. private void ReverseQuery()
  2. {
  3. int[] ints = new int[] { , , , , , , };
  4.  
  5. var result = ints.Reverse();
  6.  
  7. foreach (var re in result)
  8. {
  9.  
  10. Response.Write(re + "</br>");
  11. }
  12.  
  13. }

运行结果:

可以看出,只是把序列的元素反转了,并不会进行升序或者降序排序。

我们来看看内部实现,内部实现其实很简单:

就是对序列反向输出。

Linq查询操作之排序操作的更多相关文章

  1. 【开发者笔记】Linq 多表关联排序操作

    c# 一直是一门好用的语言,但是像linq这种骚操作实在是记不住.特此记下以备后用. var ls = from c in db.T_ProductReturnEntity join s in db. ...

  2. Linq查询数据集取得排序后的序列号(行号)

    今天群里有同学问如何用linq取结果集的行号,查了一下资料,发现linq有很简单的方法可以实现,花了几分钟写了一个测试用例,现记录下来,以备参考: /// <summary> /// 测试 ...

  3. LINQ查询基础

    一.什么是LINQ LINQ是Language Integrate Query的缩写,意为语言集成查询,是微软在.Net Framework 4.5版中推出的主要特性之一. 它为开发人员提供了统一的数 ...

  4. .NetCore 使用 Linq 动态拼接Expression表达式条件来实现 对EF、EF Core 扩展查询排序操作

    相信在使用EF的时候对查询条件或者排序上的处理令人心烦,下面我们就来动态拼接表达式解决这一问题 当我们在查询中使用Where的时候可以看到如下参数 下面我们就来扩展 Expression<Fun ...

  5. C#3.0新增功能09 LINQ 基础04 基本 LINQ 查询操作

    连载目录    [已更新最新开发文章,点击查看详细] 本篇介绍 LINQ 查询表达式和一些在查询中执行的典型操作. 获取数据源 在 LINQ 查询中,第一步是指定数据源. 和大多数编程语言相同,在使用 ...

  6. Linq查询操作之投影操作

    投影操作,乍一看不知道在说啥.那么什么是投影操作呢?其实就是Select操作,名字起的怪怪的.和Linq查询表达式中的select操作是一样的.它能够选择数据源中的元素,并指定元素的表现形式.投影操作 ...

  7. Linq查询操作之Where筛选

    筛选操作where能够处理逻辑运算符组成的逻辑表达式.比如逻辑“与”,逻辑“或”,并从数据源中筛选数据,它和where子句的功能非常相似.Enumerable类的Where()原型如下: public ...

  8. Linq查询操作之聚合操作(count,max,min,sum,average,aggregate,longcount)

    在Linq中有一些这样的操作,根据集合计算某一单一值,比如集合的最大值,最小值,平均值等等.Linq中包含7种操作,这7种操作被称作聚合操作. 1.Count操作,计算序列中元素的个数,或者计算满足一 ...

  9. C# LINQ系列:LINQ to DataSet的DataTable操作 及 DataTable与Linq相互转换

    LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...

随机推荐

  1. 【Bugly干货分享】手把手教你逆向分析 Android 程序

    很多人写文章,喜欢把什么行业现状啊,研究现状啊什么的写了一大通,感觉好像在写毕业论文似的,我这不废话,先直接上几个图,感受一下. 第一张图是在把代码注入到地图里面,启动首页的时候弹出个浮窗,下载网络的 ...

  2. 【腾讯Bugly干货分享】深入源码探索 ReactNative 通信机制

    Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 本文从源码角度剖析 RNA 中 J ...

  3. 解决SQLSERVER数据库表被琐死!

    ) )     BEGIN   Exec (@spId)   FETCH NEXT FROM TmpCursor INTO @spId   END     CLOSE TmpCursor DEALLO ...

  4. iphone按home键后,正在运行的程序是否退出了呢?

    是否一直有个疑问,当iphone手机正在运行一个APP,如果按Home键后,那么原来正在运行的程序还在运行吗?如果开发过ios程序,可能不是问题,如果没有开发过的,可能会疑惑了,我就简单的说一下.以几 ...

  5. 在同一台服务器上配置多个Tomcat

    如果要在一台服务器上配置多个Tomcat,主要就是要避免Tomcat服务器的端口冲突的问题.只需要修改CATALINA_HOME\conf\server.xml中的启动端口和连接端口就OK了! 下面我 ...

  6. Linux网络编程系列-TCP传输控制

    滑动窗口(sliding window) 滑动窗口是用于流量控制的,发送端根据接收端的处理能力发送数据,不至于造成过多的丢包. 是发送方和接收方间的协调,对方的接收窗口大小就是自己的发送窗口大小. 在 ...

  7. linux网络编程系列-网络连接的建立

    一个比较实用的连接函数,支持host为域名. #include <netdb.h> #include <sys/socket.h> #include <sys/types ...

  8. PMO到底什么样?(3)

    继续上一篇,PMO到底什么样?到这篇,本文就结束啦. 出色基地COE,4大典型职责 咱们知道悉数的公司,它都是要不断地持续改进和优化,包含公司内组织级的项目处理的机制,也需要不断的优化和进步.一般咱们 ...

  9. Atitit  J2EE平台相关规范--39个  3.J2SE平台相关规范--42个

    Atitit  J2EE平台相关规范--39个  3.J2SE平台相关规范--42个 2.J2EE平台相关规范--39个5 XML Parsing Specification16 J2EE Conne ...

  10. 完美C++(第5版)(双色)

    完美C++(第5版)(双色) 薛正华 沈庚 韦远科 译 ISBN 978-7-121-23198-8 2014年6月出版 定价:148.00元 788页 16开 内容提要 <完美C++(第5版) ...