Я пытаюсь создать общий метод поиска, который может выполнять поиск различными способами, как по возрастанию, так и по убыванию.
Основа:
IQueryable<MyModel> query = nhSession.Query<MyModel>();
Мой вопрос в том, могу ли я каким-либо образом абстрагироваться от вызова OrderBy vs OrderByDescending, поэтому мне не нужно делать это ветвление if для каждого отдельного варианта заказа, который я хочу поддерживать (упрощенный до одного столбца, но может быть более сложным заказы, включая ThenBy)?
if (orderAscending)
query = query.OrderBy(x => x.SomeProperty);
else
query = query.OrderByDescending(x => x.SomeProperty);
В идеале я хочу что-то вроде этого (псевдокод) с использованием делегатов, лямбда-функций или подобных, но не могу заставить что-то работать:
var filterFunc = orderAscending ? query.OrderBy : query.OrderByDescending;
query = filterFunc(query, x => x.SomeProperty);
или
query = query.Order(x => x.SomeProperty, orderAscending);
Я бы предпочел не использовать QueryOver, если это возможно, поскольку уже существует много другого кода, использующего ванильные вызовы LINQ. Я также пробовал .Reverse(), но, похоже, он не поддерживается поставщиком NH LINQ.
Невозможно получить весь список и перевернуть его в памяти, так как мне нужно только извлечь, например, 100 лучших из десятков тысяч строк.
Я нашел способ, создав свои собственные методы расширения, которые просто обертывают другие:
using System.Linq.Expressions;
namespace System.Linq
{
public static class MyQueryableOrderExtensions
{
public static IOrderedQueryable<TSource> OrderByDirection<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending)
{
if (ascending)
return source.OrderBy(keySelector);
else
return source.OrderByDescending(keySelector);
}
public static IOrderedQueryable<TSource> ThenByDirection<TSource, TKey>(this IOrderedQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending)
{
if (ascending)
return source.ThenBy(keySelector);
else
return source.ThenByDescending(keySelector);
}
}
}
Пример использования:
query = query
.OrderByDirection(x => x.MyProperty, orderAscending)
.ThenByDirection(x => x.OtherProperty, false);
Исправил код и немного подправил форматирование :)