2009-10-22 55 views
22

在LINQ中,是否有可能通過排序順序(升序或降序)具備有條件的順序。LINQ中有條件的「orderby」排序順序

像這樣的東西(無效代碼):

bool flag; 

(from w in widgets 
where w.Name.Contains("xyz") 
orderby w.Id (flag ? ascending : descending) 
select w) 

回答

25

如果構建了表達遞增,你可以做到這一點。使用表達式,而不是理解的表達通常更容易:

var x = widgets.Where(w => w.Name.Contains("xyz")); 
if (flag) { 
    x = x.OrderBy(w => w.property); 
} else { 
    x = x.OrderByDescending(w => w.property); 
} 

(假設Widget的property是排序的基礎上,因爲你沒有列出一個)

+0

如果他們需要或不是如何做多個排序與動態條件。 – Ruchan 2014-09-18 09:26:02

+0

只需要對'OrderBy'和'ThenBy'的結果使用不同的變量來保持不同的返回類型;否則只需將調用添加到適用的'ThenBy'或'ThenByDescending' LINQ運算符。 – Richard 2014-09-18 11:07:53

8

您可以定義基本查詢,而無需排序,然後順序根據標誌:

var query=(from w in widgets 
    where w.Name.Contains("xyz") 
    select w); 

var result = flag ? 
    query.OrderBy(w =>w) : 
    query.OrderByDescending(w = w); 
8

你可以嘗試像以下:

var q = from i in list 
     where i.Name = "name" 
     select i; 
if(foo) 
    q = q.OrderBy(o=>o.Name); 
else 
    q = q.OrderByDescending(o=>o.Name); 
14

......或者做這一切在一個聲明中

bool flag; 

var result = from w in widgets where w.Name.Contains("xyz") 
    orderby 
    flag ? w.Id : 0, 
    flag ? 0 : w.Id descending 
    select w; 
+0

如果底層數據是在SQL中,這個答案似乎最可能使用SQL的ORDERBY子句,但我不知道這個事實。 – 2014-08-27 19:05:04

1

如果排序特性Id是一個數字(或支持一元減)一個也可以這樣做:

bool ascending = ... 

collection.Where(x => ...) 
    .OrderBy(x => ascending ? x.Id : -x.Id) 
    .Select(x => ...) 

// LINQ query 
from x in ... 
orderby (ascending ? x.Id : -x.Id) 
select ... 
0

MoreLINQ的NuGet package也提供了擴展方法,使this更方便。 它還提供了許多更有用的擴展方法,因此是我項目中的一個穩定的擴展方法。

3

這是一個更一般的解決方案,它可以用於各種條件lambda表達式而不會破壞表達式的流程。

public static IEnumerable<T> IfThenElse<T>(
    this IEnumerable<T> elements, 
    Func<bool> condition, 
    Func<IEnumerable<T>, IEnumerable<T>> thenPath, 
    Func<IEnumerable<T>, IEnumerable<T>> elsePath) 
{ 
    return condition() 
     ? thenPath(elements) 
     : elsePath(elements); 
} 

例如

var result = widgets 
    .Where(w => w.Name.Contains("xyz")) 
    .IfThenElse(
     () => flag, 
     e => e.OrderBy(w => w.Id), 
     e => e.OrderByDescending(w => w.Id)); 
0

你甚至可以做更復雜的排序,並仍然保持短:

var dict = new Dictionary<int, string>() { [1] = "z", [3] = "b", [2] = "c" }; 
    var condition = true; 
    var result = (condition ? dict.OrderBy(x => x.Key) : dict.OrderByDescending(x => x.Value)) 
     .Select(x => x.Value);