程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Linq查詢操作之排序操作

Linq查詢操作之排序操作

編輯:關於.NET

  在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)
{
    return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false);
}

 
2、public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
    return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, false);
}

 

 


 

其中source表示數據源,keySelector表示獲取排序的關鍵字的函數,comparer參數表示排序時的比較函數。TSource表示數據源的類型,TKey表示排序關鍵字的類型。下面我們用兩種方式來比較排序,第一種按照前面講的查詢表達式來排序,第二種用現在的排序操作來排序,其實結果都是一樣的。

private void OrderByQuery()
        {
            int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };

            //使用查詢表達式來排序

            Response.Write("--------------使用查詢表達式來排序---------</br>");
            var values = from v in ints

                         orderby v

                         select v;

            foreach (var item in values)
            {

                Response.Write(item+"</br>");
            }
             //使用排序操作來排序

            Response.Write("--------------使用排序操作來排序---------</br>");

            var result = ints.OrderBy(x => x);

            foreach (var re in result)
            {

                Response.Write(re + "</br>");
            }

        }

看看運行結果:

我們看到和我們預想的是一樣的。那麼大家可能有些疑問,為什麼OrderBy是升序排序呢?

我們來從源碼解析一下:

我們看到OrderBy裡面最終調用了一個函數OrderedEnumerable,那麼我們再來看看這個OrderedEnumerable函數:

看到這個函數有一個參數descending,我們OrderBy方法給這個參數傳了false,那麼就表示非降序排序,就是升序排序。可想而知,OrderByDescending操作,給這個參數傳值應該是true。

第二個原型裡面有個comparer參數,那麼我們來看看怎麼用:既然是IComparer接口類型的參數,那麼我們就定義一個實現了Icomparer接口的類型:

 private void OrderByQuery()
         {
             int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };
 
 
             var result = ints.OrderBy(x => x,new CompareIntegers());
 
             foreach (var re in result)
             {
 
                 Response.Write(re + "</br>");
             }
 
         }
 
         public class CompareIntegers : IComparer<int>
         {
             public int Compare(int i1, int i2)
             {
                 return -1*(i1 - i2);
             }
         }

我們看到,我們定義的CompareIntegers類的比較參數是,該元素取反,所以排序結果應該就成了降序排序了。我們看看測試結果:

嗯和我們預想的一樣,這個comparer函數就是我們自定義的比較方式。

OrderByDescending操作

  OrderByDescending和我們上面的OrderBy操作相似,最終都是調用OrderedEnumerable只是傳入的descending參數的值不同。看看OrderByDescending的原型:

    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

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

也有兩個原型,跟OrderBy的原型一模一樣,只是最終調用OrderedEnumerable方法的傳入參數不同。

我們看到這個傳入的是true,表示降序排列。所以我個人覺得這兩個操作可以合並,然後多一個參數而已。

同樣寫個例子測試一下:

  private void OrderByDescendingQuery()
         {
             int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };
 
             //使用查詢表達式來排序
 
             Response.Write("--------------使用查詢表達式來排序---------</br>");
             var values = from v in ints
 
                          orderby v descending
 
                          select v;
 
             foreach (var item in values)
             {
 
                 Response.Write(item+"</br>");
             }
          //使用排序操作來排序
 
             Response.Write("--------------使用排序操作來排序---------</br>");
 
             var result = ints.OrderByDescending(x => x);
 
             foreach (var re in result)
             {
 
                 Response.Write(re + "</br>");
             }
 
         }

看看測試結果:

嗯結果和預想的一樣。

ThenBy操作

  上面兩個排序都是按照主關鍵字來排序的,下面呢我們就看看什麼是按照次要關鍵字排序。ThenBy 和OrderBy一樣是按照升序排序的。來看看原型:

    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector);
    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做次要關鍵字。

 private void ThenByQuery()
         {
             IList<UserBaseInfo> users = new List<UserBaseInfo>();
 
             for (int i = 1; i < 10; i++)
             {
                 users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
             }
 
             var values = users.OrderBy(u => u.ID).ThenBy(x => x.UserName);
 
             foreach (var u in values)
             {
                 Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
             }
 
 
         }

看看結果:

ThenByDescending操作

  這個是ThenBy的降序排序方式,和前面的用法實質是一樣的,我就不詳細講解了,大家可以自己研究一下。

Reverse操作

  下面我們就來看看Reverse這個排序。這個排序呢可以說也不算是排序,因為我們知道排序無非就是升序,或者降序。這個其實就是將一個序列進行反轉,裡面的值如果本來沒有順序,執行這個操作之後,也不會變得有序,只是序列的元素反轉。

看看reverse的原型:

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

測試樣例:

 private void ReverseQuery()
         {
             IList<UserBaseInfo> users = new List<UserBaseInfo>();
 
             for (int i = 1; i < 10; i++)
             {
                 users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
             }
 
             var values = users.Reverse();
 
             foreach (var u in values)
             {
                 Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
             }
 
 
         }

運行結果:

看確實是反轉了。

  再看一個本來無序的例子。

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

運行結果:

可以看出,只是把序列的元素反轉了,並不會進行升序或者降序排序。

我們來看看內部實現,內部實現其實很簡單:

就是對序列反向輸出。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved