2012-03-26 61 views
1

我實現排序基於參數傳遞到升序或降序排序依據方法倒車基礎上通過的財產IQueryable的排序邏輯

else if (showGrid.Sortdir == "DESC") 
        { 
         alerts = DB.Incidents.OfType<Alert>().Where(
          a => 
          a.IncidentStatusID == (int)AlertStatusType.New || 
          a.IncidentStatusID == (int)AlertStatusType.Assigned || 
          a.IncidentStatusID == (int)AlertStatusType.Watching) 
          .OrderByDescending(a => showGrid.Sort); 
        } 
        else 
        { 
         alerts = DB.Incidents.OfType<Alert>().Where(
          a => 
          a.IncidentStatusID == (int)AlertStatusType.New || 
          a.IncidentStatusID == (int)AlertStatusType.Assigned || 
          a.IncidentStatusID == (int)AlertStatusType.Watching) 
          .OrderBy(a => showGrid.Sort); 
        } 

在升序排序的情況下它工作正常,但對於降序排序不工作。我調試了代碼,發現列表並不像升序那樣受到尊崇。請幫我

+0

聽起來像是'Sortdir適用您的排序'不完全是「DESC」。我建議你在兩個分支中進行日誌記錄(或者調試代碼)以查看實際採用的路徑。 – 2012-03-26 10:49:02

+0

我已經厭倦了它使用「ASC」和「DESC」的相應路徑。而調試我把'警報'的值,我可以看到,當它執行OrderByDesending(a => showGrid.Sort)時,這些項目並不受尊敬; – 2012-03-26 10:57:07

+0

什麼是'showGrid.Sort'?你用什麼樣的LINQ提供商開始? – 2012-03-26 11:01:15

回答

0

好的。我寫了一個小測試。這很有趣,但你的代碼實際上可以編譯和工作,但是與你期望的很不一樣:) 顯然showGrid不是Alert類型,它是一些其他類的實例,順便說一下,它具有與Alert相同的屬性,稱爲分類。 首先我很困惑,因爲期望這段代碼無法編譯。

// The signature of OrderBy 
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector) 

// In your case it will result in 
public static IOrderedQueryable<Alert> OrderBy<Alert, string>(this IQueryable<Alert> source, Expression<Func<Alert, string>> keySelector) 
//when you call it like you do 
DB.Incidents.OfType<Alert>().OrderByDescending(a => showGrid.Sort); 
// You supply a property from object of type different from your entity. 
// This is incorrect usage, the only object you can use here is the 
// "a" argument. Like this: 
DB.Incidents.OfType<Alert>().OrderByDescending(a => a.Sort); 
// Because anything else does not make any sense to entity provider. 

所以你的訂單根本不起作用。

據我所知,你想要的是基於UI中的選擇進行排序。這在強類型的LINQ中不容易實現。因爲正如我上面所展示的,你發送一個屬性,而不是OrderBy的值。它不關心道具內的價值。因此,有幾種解決問題的方案:

  1. 寫一個大的開關,將檢查每一個可能的排序值,並會追加相應的「排序依據(A => a.YouPropToSort)」來查詢。這很直截了當,你應該從這個開始。當然這是一種靜態的方式,每次你想要添加新列以進行排序時,都需要更改代碼。
  2. 使用'LINQ Expression Trees'爲OrderBy創建參數。對於你來說,這不應該很難做到。尋找這個詞,你會發現很多例子。
  3. 嘗試使用動態LINQ。我自己並沒有使用它,只是看着文檔。這似乎是對常規LINQ的擴展,它允許您將部分查詢寫爲字符串,以克服當前動態排序的限制。
0

這裏是我的解決方案來排序基於用戶選擇:

創建基本的查詢

var query = DB.Incidents.OfType<Alert>.Where(
         a => 
         a.IncidentStatusID == (int)AlertStatusType.New || 
         a.IncidentStatusID == (int)AlertStatusType.Assigned || 
         a.IncidentStatusID == (int)AlertStatusType.Watching); 

,然後使用一個case語句

bool desc = showGrid.SortDir = "DESC"; 

switch(showGrid.Sort) 
{ 
    case "col1": 
     query = desc ? query.OrderByDescending(a => a.Col1) : query.OrderBy(a => a.Col1); 
     break; 
    case "col2": 
     query = desc ? query.OrderByDescending(a => a.Col2) : query.OrderBy(a => a.Col2); 
     break; 
    ... 
} 

var results = query.ToList(); 
+0

這是不正確的。 'QueryType'支持'OfType'以獲得特定的被刪除的實體,它不會迭代該集合。 – 2012-03-26 12:46:55

+0

好的,我站好了。我必須測試這個來說服自己,但現在沒有時間。相應地更改了答案。 – Phil 2012-03-26 13:01:10

+0

以下是來自Queryable源的引用:'public static IQueryable OfType (this IQueryable source)'所以你可以肯定:) – 2012-03-26 13:05:41