Создать отсортированный список с использованием дерева выражений

У меня есть коллекция типа IQueryable, мне нужно отсортировать ее на основе некоторых полей динамической сортировки. Поля сортировки находятся внутри списка.

Для этого я пишу следующий метод.

public List<T> Order<T>(IQueryable<T> source, List<string> propertyNames)
    {

        if (propertyNames != null && propertyNames.Count > 0)
        {
            var param = Expression.Parameter(typeof(T), string.Empty);
            var property = Expression.PropertyOrField(param, propertyNames[0]);

            var sort = Expression.Lambda(property, param);
            MethodCallExpression orderByCall = Expression.Call(typeof(Queryable),"OrderBy",new[] { property.Type },Expression.Quote(sort));
            if (propertyNames.Count > 1)
            {
                foreach(var item in propertyNames)
                {
                    param = Expression.Parameter(typeof(T), string.Empty);
                    property = Expression.PropertyOrField(param, item);

                    sort = Expression.Lambda(property, param);

                    orderByCall = Expression.Call(
                        typeof(Queryable),
                        "ThenBy", new[] { typeof(T), property.Type },
                        orderByCall,
                        Expression.Quote(sort));
                }
            }

            var results = (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(orderByCall);
            if (results != null)
             return results.ToList();

        }

        return null;
    }

когда я выполнил MethodCallExpression orderByCall = Expression.Call(typeof(Queryable),"OrderBy",new[] { property.Type },Expression.Quote(sort));, у меня возникло исключение

No generic method 'OrderBy' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

stackoverflow.com/questions/17943024/…
Salah Akbari 17.12.2018 08:51

не связанный: if (propertyNames?.Count > 0)

Patrick Artner 17.12.2018 09:17

Кроме того, действительно ли это должно быть сделано на IQueryable (т.е. до того, как запрос будет отправлен в базу данных)? Если сортировку можно выполнить по списку IList (т.е. после того, как он возвращается из базы данных), это становится проще.

James Curran 17.12.2018 21:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
83
1

Ответы 1

Извините, у меня нет прямого решения вашей ошибки.

Вот альтернативный («простой») подход к динамическому упорядочиванию ваших данных.

1) Добавьте эти методы расширения где-нибудь в свой проект

public static IOrderedQueryable<TSource> OrderBy<TSource, TProperty>(this IQueryable<TSource> source
      , Expression<Func<TSource, TProperty>> expression, bool descending)
{
      return !descending ? source.OrderBy(expression) : source.OrderByDescending(expression);
}

public static IOrderedQueryable<TSource> ThenBy<TSource, TProperty>(this IOrderedQueryable<TSource> source
  , Expression<Func<TSource, TProperty>> expression, bool descending)
{
  return !descending ? source.ThenBy(expression) : source.ThenByDescending(expression);
}

2) Теперь вы можете просто зациклить список имен свойств и применить OrderBy / ThenBy к своему IQueryable.

Другая идея: вы можете адаптировать свой метод так, чтобы он принимал выражения вместо строк с именами свойств.

Другие вопросы по теме