2015-02-05 53 views
1

我有3個項目要由Linq進行排序。對Linq查詢中的數據進行排序

的3項是

  1. 1.1 AAAAAA
  2. 10.1 AAAAA
  3. 1.11 AAAAA
  4. 9.1 AAAAAA

的排序列表應儘可能

  1. 1.1 AAAAA
  2. 1.11 AAAA
  3. 9.1 AAAAA
  4. 10.1 AAAA

這裏是我的代碼:

var progTypes = (from mnuit in entities.MENU_ITEM 
       join mnu in entities.MENU on mnuit.MENU_ID equals mnu.MENU_ID 
       join prog in entities.PROG on mnuit.MENU_ITEM_ID equals prog.PROG_TYP_ID 
       where (mnuit.MENU_ITEM_CD == programmodel.selectedProgram && mnu.MENU_NM == "PROG_TYP_ID") 
       select new ProgramModel.lstProgTypes 
         { 
          PROG_ID = prog.PROG_ID, 
          PROG_NBR = prog.PROG_NBR, 
          PROG_NM = prog.PROG_NM, 
          PROG_MAX_AMT = prog.PROG_MAX_AMT, 
          PROG_START_DT = prog.PROG_START_DT, 
          PROG_END_DT = prog.PROG_END_DT 
         }).OrderBy(m => m.PROG_NM) 
          .ToList(); 

progModel.mProgTypes = progTypes; 

你們可以請幫

+1

和你嘗試過什麼? – 2015-02-05 21:14:14

+1

請詳細說明如何定義排序順序 – DixonD 2015-02-05 21:14:30

+6

不要將兩個(編輯:顯然是其三個)不同的值存儲在一個列中。將它們存儲在各自的專欄中;那麼查詢就變得微不足道了。 – Servy 2015-02-05 21:15:09

回答

0

看來,字符串代表本質上是複合的東西。處理這種情況的理想方法是而不是存儲複合材料,而是存儲各個部分。在你的情況下,這意味着在三個獨立的屬性中存儲一個數字,另一個數字和一個字符串。

但是,這並不總是可能的,也許是因爲您正在處理遺留系統,而選擇了糟糕的設計選項,現在您仍然堅持使用它。處理這種情況的一種方法是將數據存入內存,並使用自定義的IComparer<T>進行分類。

從查詢中刪除OrderBy(...)開始。由於您已經撥打ToList(),因此progTypes將在內存中包含其所有元素。這就是你想要的方式。現在,您可以定義自定義比較,並做到這一點:

progTypes = progTypes.OrderBy(m => m.PROG_NM, new NmComparer()).ToList(); 

「魔術師」進入NmComparer

internal class NmComparer : IComparer<string> { 
    public int Compare(string a, string b) { 
     var tokA = a.Split('.', ' '); 
     var tokB = b.Split('.', ' '); 
     int res = int.Parse(tokA[0]).CompareTo(int.Parse(tokB[0])); 
     if (res != 0) return res; 
     res = int.Parse(tokA[1]).CompareTo(int.Parse(tokB[1])); 
     if (res != 0) return res; 
     return tokA[2].CompareTo(tokB[2]); 
    } 
} 

的比較器假定PROG_NM有三個部分 - 兩個int S和string 。它將雙方分成一個點和一個空格,然後將結果從左到右進行比較,並將左側的令牌優先。

0

如果你真的必須將它全部存儲在一個字段中。基本上我只做三種。我已經添加了更多示例來更清楚地說明它的工作原理。

var list = new List<string> 
{ 
    "1.1 AAAAAA", 
    "10.1 AAAAA", 
    "1.12 AAAAA", 
    "1.11 AAAAA", 
    "9.1 BAAAAA", 
    "9.1 AAAAAA" 
}; 

var result = from s in list 
      let indexOfDot = s.IndexOf('.') 
      let indexOfSpace = s.IndexOf(' ') 
      orderby s.Substring(indexOfSpace) 
      orderby Convert.ToInt32(s.Substring(indexOfDot + 1, indexOfSpace - indexOfDot)) 
      orderby Convert.ToInt32(s.Substring(0, indexOfDot)) 
      select s; 

可以在LINQPad測試 - http://share.linqpad.net/8p23tu.linq

相關問題