【发布时间】:2009-10-22 10:59:44
【问题描述】:
在 LINQ 中,是否可以按排序顺序(升序与降序)进行条件排序。
类似这样的东西(无效代码):
bool flag;
(from w in widgets
where w.Name.Contains("xyz")
orderby w.Id (flag ? ascending : descending)
select w)
【问题讨论】:
在 LINQ 中,是否可以按排序顺序(升序与降序)进行条件排序。
类似这样的东西(无效代码):
bool flag;
(from w in widgets
where w.Name.Contains("xyz")
orderby w.Id (flag ? ascending : descending)
select w)
【问题讨论】:
如果您以增量方式构建表达式,则可以这样做。通常使用表达式比使用理解表达式更容易:
var x = widgets.Where(w => w.Name.Contains("xyz"));
if (flag) {
x = x.OrderBy(w => w.property);
} else {
x = x.OrderByDescending(w => w.property);
}
(假设小部件的 property 是排序的基础,因为您没有列出一个。)
【讨论】:
OrderBy和ThenBy的结果使用不同的变量来保持不同的返回类型;否则只需添加对适用的ThenBy 或ThenByDescending LINQ 运算符的调用。
...或者在一个语句中完成所有操作
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;
【讨论】:
这是一个更通用的解决方案,可用于各种条件 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));
【讨论】:
elsePath 成为可选参数
e => e 用于elsePath,枚举将按原样返回。
您可以定义一个没有排序的基本查询,然后根据标志排序:
var query=(from w in widgets
where w.Name.Contains("xyz")
select w);
var result = flag ?
query.OrderBy(w =>w) :
query.OrderByDescending(w = w);
【讨论】:
您可以尝试以下方法:
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);
【讨论】:
如果排序属性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 ...
【讨论】:
您甚至可以进行更复杂的排序并保持简短:
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);
【讨论】: