C# LINQ 中的条件“orderby”排序顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1606454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:18:27  来源:igfitidea点击:

Conditional "orderby" sort order in LINQ

c#.netlinq

提问by xyz

In LINQ, is it possible to have conditional orderby sort order (ascending vs. descending).

在 LINQ 中,是否可以有条件 orderby 排序顺序(升序与降序)。

Something like this (not valid code):

像这样(无效代码):

bool flag;

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

采纳答案by Richard

If you build the expression incrementally you can do this. Generally easier using expressions rather than comprehension expressions:

如果您逐步构建表达式,则可以执行此操作。通常更容易使用表达式而不是理解表达式:

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

(Assuming the Widget's propertyis basis of sort since you don't list one.)

(假设 Widgetproperty是排序的基础,因为您没有列出一个。)

回答by Konamiman

You can define a base query without the ordering, then order according to the flag:

您可以定义一个没有排序的基本查询,然后根据标志进行排序:

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

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

回答by cloggins

You could try something like the following:

您可以尝试以下操作:

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);

回答by Carter Medlin

...Or do it all in one statement

...或者在一个声明中完成所有操作

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;

回答by Julian Lettner

If the ordering property Idis a number (or supports the unary minus) one could also do:

如果 ordering 属性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 ...

回答by Julian Lettner

The MoreLINQNuGet packagealso provides extension methods to make thismore convenient. It also provides many more helpful extension methods and is therefore a stable go-to in my projects.

MoreLINQ的NuGet还提供扩展方法,使这个更方便。它还提供了许多更有用的扩展方法,因此在我的项目中是一个稳定的选择。

回答by Jezze

Here is a more general solution, that can be used for various conditional lambda expressions without breaking the flow of the expression.

这是一个更通用的解决方案,可用于各种条件 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);
}

e.g.

例如

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

回答by watbywbarif

You can even do more complex ordering and still keep it short:

您甚至可以进行更复杂的排序,但仍然保持简短:

    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);