2009-10-22 52 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);