2012-05-11 111 views
6

我檢查的排序參數,構建了一堆if聲明:我該如何改進這個排序代碼?

if (sortDirection == "ASC") 
{ 
    if (sortBy == "Id") 
     return customerList.OrderBy(x => x.Id).Skip(startIndex).Take(pageSize).ToList(); 
    if (sortBy == "FirstName") 
     return customerList.OrderBy(x => x.FirstName).Skip(startIndex).Take(pageSize).ToList(); 
    if (sortBy == "City") 
     return customerList.OrderBy(x => x.City).Skip(startIndex).Take(pageSize).ToList(); 
} 
else 
{ 
    if (sortBy == "Id") 
     return customerList.OrderByDescending(x => x.Id).Skip(startIndex).Take(pageSize).ToList(); 
    if (sortBy == "FirstName") 
     return customerList.OrderByDescending(x => x.FirstName).Skip(startIndex).Take(pageSize).ToList(); 
    if (sortBy == "City") 
     return customerList.OrderByDescending(x => x.City).Skip(startIndex).Take(pageSize).ToList(); 
} 

如何做得更好?

+6

定義「更好」。更好的是什麼? – Oded

+1

你想以什麼方式「改善」它?它是否按預期工作?它太慢了嗎?你不喜歡代碼的結構嗎?我們需要更多信息。 –

+0

我會推薦使用LINQ組合。請參閱http://stackoverflow.com/questions/5881107/how-can-i-build-entity-framework-queries-dynamically/5882243#5882243 – Euphoric

回答

8

獨立的訂貨和查詢的其餘部分 - 這是你沒​​有在你的代碼複製每個查詢相同的部分(保持DRY):

var query = customerList; 

if (sortDirection == "ASC") 
{ 
    if (sortBy == "Id") 
     query = query.OrderBy(x => x.Id); 
    ///and so on 
} 

query = query.Skip(startIndex).Take(pageSize).ToList(); 
+0

這仍然是很多所有領域的樣板,不會反射會更清潔?想象一下,如果他有50場! :) – mattytommo

+0

@NiklasB。這將是問題,因爲OrderBy是通用的,並且lambda對於每個屬性都有不同的類型。除非你想將它轉換爲任何地方的對象。 – Euphoric

+0

@mattytommo:如果這是一個內存集合,這當然是可能的和整潔的 – BrokenGlass

2

使用反射:)

customerList = (sortDirection == "ASC") 
    ? customerList 
     .OrderBy(x => x.GetType().GetProperty(sortBy).GetValue(x, null)) 
     .Skip(startIndex) 
     .Take(pageSize) 
     .ToList() 
    : customerList 
     .OrderByDescending(x => x.GetType().GetProperty(sortBy).GetValue(x, null)) 
     .Skip(startIndex) 
     .Take(pageSize) 
     .ToList(); 
1

它看起來像你只是想通過屬性名稱作爲字符串進行排序。在這種情況下,這其實已經可以通過「動態LINQ」解決:

Dynamic LINQ OrderBy on IEnumerable<T>

看看這個問題的答案,它應該爲你提供的示例代碼爲您解決問題。