成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

輕輕松松學習Linq排序

開發 后端
Linq排序在一系列Linq操作中應該使用頻率最高的,關于Linq排序的文章也很多,但是筆者的這篇文章最值得一讀了,因為他把理論與實踐結合的十分完美,理解起來也很簡單,希望能給你帶來幫助。

Linq排序在一系列Linq操作中應該使用頻率***的,關于Linq排序的文章也很多,但是筆者的這篇文章最值得一讀了,因為他把理論與實踐結合的十分***,理解起來也很簡單,希望能給你帶來幫助。

在程序開發中,對數據進行排序是很常見的操作。現在就來演示一下Linq排序,假設現在有一個類Customer,定義如下所示:

  1. public class Customer  
  2. {  
  3. public string Id { getset; }  
  4. public string Name { getset; }  
  5. public decimal Age { getset; }  

我們現在要對很多Customer對象進行排序,最簡單的就是使用Linq排序的orderby子句:

  1. from c in Customers orderby c.Id select c; 

上面實現了按照Id來進行Linq排序。可是需求變了,用戶現在想用Name來排序。好辦!把上面的改一改比如下面這樣就可以了:

  1. from c in Customers orderby c.Name select c; 

可是需求又變了,用戶現在說,你在程序中不能寫死,得列一個菜單,我點哪個你就按哪個給我Linq排序。這個也不難辦:

  1. var searchResult = from c in Customers select c;  
  2. if (columnName == "Id")  
  3. {  
  4. searchResult = from c in Customers orderby c.Id select c;  
  5. }  
  6. else if (columnName == "Name")  
  7. {  
  8. searchResult = from c in Customers orderby c.Id select c;  
  9. }  
  10. else ...  

這確實解決了問題,可是這樣的代碼不易維護。如果加屬性了怎么辦?如果屬性改名字了怎么辦?如果有好多的不同的類都需要這樣的Linq排序怎么辦?

下面我介紹一種較為通用的解決方案,此方案的核心技術是反射(Reflection)和擴展方法(Extension Methods)。

  1. public static IOrderedQueryable OrderBy(  
  2. this IQueryable source,  
  3. Expression> keySelector,  
  4. IComparer comparer  

參數source是一個用來排序的對象,keySelector是用來取出用來Linq排序的鍵的函數,comparer(比較器)用來比較取出的兩個鍵值。

對象的屬性類型可能多種多樣,而我們又不想為每種類型分別指定comparer(因為那樣做的話也將是一堆if else…)。變通一下思路,不管遇到哪種類型的屬性,我們都先把它的值放到一個共同的容器中,然后為這個容器寫一個comparer類。我們把類型判斷留到了這個comparer中,因為類型是有限的,至少我們需要處理的那些屬性的類型是有限的。
上面提到的這個值的容器也是一個類,定義如下:

  1. public class CommonComparableValue  
  2. {  
  3. public object RealValue { getset; }  

相應的比較類定義如下:

  1. public class CommonComparableValueComparer : IComparer  
  2. {  
  3. public int Compare(CommonComparableValue x, CommonComparableValue y)  
  4. {  
  5. string s = x.RealValue as string;  
  6. if (s != null)  
  7. {  
  8. return s.CompareTo(y.RealValue);  
  9. }  
  10. int? i = x.RealValue as int?;  
  11. if (i != null)  
  12. {  
  13. return i.Value - (int)y.RealValue;  
  14. }  
  15. decimal? d = x.RealValue as decimal?;  
  16. if (d != null)  
  17. {  
  18. return d.Value.CompareTo((decimal)y.RealValue);  
  19. }  
  20. throw new NotImplementedException("NotImplemented Data Type!!!");  
  21. }  

這里的比較類只用到了int,string等幾種類型,如果屬性有其它的類型,也應該在這里添加。從代碼實現可以看出,即使屬性的類型是復雜數據類型也可以這么處理。

現在來看keySelector的實現。它是用來取出待比較的屬性值的函數。這個函數應該是這個樣子的:

  1. public delegate TResult Func  
  2. ( T  arg ) 

在這里,T的類型就是Customer,TResult就是剛剛已經那個存放任意屬性類型的值的容器CommonComparableValue。

在這個實現取鍵值的函數里,我們只有一個Customer類型的參數arg可用,而那個用來Linq排序的屬性名字是在運行期間確定的,如何才能取出我們想要的屬性的值呢?方法是這樣的,先通過擴展方法為Customer加一個名為GetSortingKeyValue的取鍵值方法,代碼如下:

  1. public static class CustomerSortExtension  
  2. {  
  3. public static CommonComparableValue GetSortingKeyValue(this Customer ainfo, string columnName)  
  4. {  
  5. Type t = ainfo.GetType();  
  6. PropertyInfo pinfo = t.GetProperty(columnName);  
  7. if (pinfo == null)  
  8. {  
  9. throw new Exception("Property " + columnName + "not found");  
  10. }  
  11. else 
  12. {  
  13. return new CommonComparableValue  
  14. {  
  15. RealValue = pinfo.GetValue(ainfo, null)  
  16. };  
  17. }  
  18. }  

這里就是通過一個字符串獲取屬性值,核心是反射。接下來只要在那個keySelector方法中調用GetSortingKeyValue方法就可以了。

到這里,各種準備活動就做完了。現在來看一下怎么把這些東西組織起來實現Linq排序:

  1. var searchResult = from c in Customers select c;  
  2. Func myFunc = x => x.GetSortingKeyValue(columnName);  
  3. CommonComparableValueComparer comparer = new CommonComparableValueComparer();  
  4. searchResult = searchResult.OrderBy(myFunc, comparer); 

這種方案的主要內容到這里就介紹完了。

***提一下,如果你想把這些東西用到你的代碼中,你一般需要做的只有:將擴展方法的***個參數改為你需要Linq排序的那個類型。比如要為Person排序,擴展方法則可以是這個樣子:

  1. public static CommonComparableValue GetSortingKeyValue(this Customer ainfo, string columnName) 

當然,那個CommonComparableValueComparer類也應該根據實際類型修改以支持更多的屬性類型。

以上就是對Linq排序的詳細介紹,從理論到方法,很有價值的一篇文章呦!

【編輯推薦】

  1. 為你揭曉 Linq更新數據是否真的實用?
  2. 深度剖析linq級聯刪除
  3. 簡單實現Linq連接查詢
  4. LINQ動態查詢的實現淺析
  5. 簡單實現Linq多條件查詢
責任編輯:阡陌 來源: 博客園
相關推薦

2010-03-03 18:13:23

Android組成框架

2010-01-14 16:10:21

C++開發

2010-01-15 10:14:21

C++ Builder

2009-11-09 15:41:14

WCF安全性

2009-11-10 15:44:17

VB.NET常量

2010-01-18 11:20:58

C++語言

2010-03-01 17:32:21

Python 測試模塊

2010-01-26 14:53:43

C++

2010-01-20 10:31:18

C++編程技術

2010-01-20 18:17:55

C++異常問題

2009-06-10 17:58:41

2017-10-27 12:00:28

MySQL數據庫優化

2015-09-22 10:31:11

2019-11-28 10:21:01

MySQLDocker數據

2011-04-28 15:41:02

打印機卡紙

2010-08-30 09:27:20

2009-11-11 09:31:44

ADO.NET事務處理

2009-02-20 13:39:01

2021-11-07 06:52:44

Windows 11操作系統微軟

2019-05-28 15:05:10

NginxTomcat負載均衡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩电影一区 | 欧美日韩不卡合集视频 | 久久久久久999 | 亚洲精品一区二区三区 | 亚洲一区二区在线免费观看 | 亚洲欧美国产精品一区二区 | 成人午夜精品 | 草久视频 | 91免费观看视频 | 久久精品a级毛片 | 99精品国产一区二区三区 | 国产精品完整版 | 久久久www成人免费精品 | 成年免费视频 | av毛片 | 嫩草影院网址 | 国产91观看| 国产成人a亚洲精品 | 国产高潮好爽受不了了夜色 | 亚洲69p | 成人av一区二区亚洲精 | 99一级毛片 | 久久久久久亚洲精品不卡 | 久久精品日产第一区二区三区 | 国产成人精品久久二区二区91 | 国产精品一区二区在线播放 | 国产做a爱片久久毛片 | 男人的天堂久久 | 91视频88av | 欧美一区二区三区视频在线 | 精品一区二区三区av | www视频在线观看 | 中文字幕亚洲区一区二 | 99re在线视频 | 91网站在线播放 | 国产亚洲精品久久19p | 亚洲国产成人精品久久 | 亚洲自拍偷拍av | 精品久久久久久中文字幕 | 久久精品91 | 欧美三区在线观看 |