Подтвердить что ты не робот

Условный порядок упорядочения в LINQ

В LINQ можно ли условно упорядочить порядок сортировки (восходящий или нисходящий).

Что-то вроде этого (неверный код):

bool flag;

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

Ответ 1

Если вы построите выражение постепенно, вы можете это сделать. Как правило, проще использовать выражения, а не выражения понимания:

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 является базой сортировки, так как вы его не перечислили.)

Ответ 2

... Или все это в одном утверждении

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;

Ответ 3

Вы можете определить базовый запрос без заказа, затем заказывать в соответствии с флагом:

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

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

Ответ 4

Вы можете попробовать что-то вроде следующего:

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

Ответ 5

Вот более общее решение, которое может быть использовано для различных условных лямбда-выражений без нарушения потока выражения.

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

Ответ 6

Если свойство order 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 ...

Ответ 7

MoreLINQ NuGet package также предоставляет методы расширения, чтобы сделать это более удобным. Он также предоставляет множество полезных методов расширения и, следовательно, является стабильным в моих проектах.

Ответ 8

Вы даже можете сделать более сложный порядок и по-прежнему держать его коротким:

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