Почему не получается встроить сортировку в IQueryable?

Ссылка скопирована
1 ответ

Приветствую!
У меня есть отсортированный список лонгов List numbers.
Так же у меня есть таблица в бд Records (id, name, desc).
Я хочу составить объект запроса IQueryable к этой таблице.
Но мне нужно что бы список записей/сущностей из таблицы в рамках запроса был отсортирован, сортировка в оперативной памяти не подходит.
Сортировка должна происходить по полю Records.id на основе порядка лонгов в списке numbers.
На просторах сети был найдет вот такой метод, который вроде бы эту задачу решает.

public IQueryable<Entity> Sort(IQueryable<Entity> query, List<int> ids)         {                      var count = ids.Count;              for (int i = 0; i < count; ++i)             {                 int value = ids[i];                 if (query is IOrderedQueryable<Entity> orderedQuery)                 {                     query = orderedQuery.ThenBy(d => d.Id == value);                 }                 else                 {                     query = query.OrderBy(d => d.Id == value);                 }             }             return query;         }

public IQueryable<Entity> Sort(IQueryable<Entity> query, List<int> ids) { var count = ids.Count; for (int i = 0; i < count; ++i) { int value = ids[i]; if (query is IOrderedQueryable<Entity> orderedQuery) { query = orderedQuery.ThenBy(d => d.Id == value); } else { query = query.OrderBy(d => d.Id == value); } } return query; }

Но в момент его вызова, на этапе query = orderedQuery.ThenBy(d => d.Id == value) вылетает исключение:
Expression of type..IQueryable cannot be used for parameter of type IOrderedQueryable..
Непонятно, вроде бы запрос приводится к IOrderedQueryable, но при этом падает в исключение..
Прошу помочь разобраться.

Дополнительно:

1. Если тебе нужен такой порядок сортировки, то стоит дважды подумать, зачем тебе это и можно ли как-то от такого ограничения избавиться.

2. В принципе ты можешь сделать временную таблицу, затолкать в неё эти числа и сделать JOIN с таблицей Records - тогда результат выйдет в том порядке, в котором у тебя лежать эти числа.

На просторах сети был найдет вот такой метод, который вроде бы эту задачу решает.

Вот так делать точно не стоит. Сколько у тебя там айдишников?

сортировка в оперативной памяти не подходит.

СУБД точно также такую сортировку будет делать в оперативной памяти. Ты просто двигаешь нагрузку с твоего приложения на сервер СУБД и добавляет ему работы по разбору большого запроса.

  • Василий Банников,

    Сколько у тебя там айдишников?

    В отсортированном списке numbers 7 значений типа long.
    Если речь про кол-во записей в таблице Records то там 1313 записей. Кол-во растет с каждым днём. Собственно как и кол-во значений в списке numbers со временем может становится больше.

  • Василий Банников,

    стоит дважды подумать, зачем тебе это и можно ли как-то от такого ограничения избавиться

    Я бы хотел, но других вариантов не вижу.

  • Могу предположить, что в OrderBy (ThenBy) в должно указываться поле для сортировки, а не булевое выражение. Возможно Ваш адаптер к базе данных не может правильно интерпретировать это выражение в SQL и выдаёт ошибку.
  • CityzenUNDEAD, и в первую очередь должны идти элементы из списка?
    Тогда можно сделать просто select where in и через union объеденить с select where not in
  • CityzenUNDEAD, нужно не другие варианты искать, а саму причину появления такого требования смотреть.
  • CityzenUNDEAD, но ты же не всю тысячу элементов выбираешь, верно?
  • Василий Банников, не, элементы из списка нужны только для сортировки. Они в выборке полученной из бд присутствовать не будут.
  • CityzenUNDEAD, а в чём тогда смысл, если их нет в выборке? Что ты сортировать собрался?
  • Василий Банников,

    но ты же не всю тысячу элементов выбираешь, верно?

    Все) А на фронте эта тысяча элементов постранично разбивается.

  • Василий Банников,

    а в чём тогда смысл, если их нет в выборке? Что ты сортировать собрался?

    Записи из таблицы Records, их нужно отсортировать. А numbers нужен только для порядка сортировки, если можно так выразиться.

  • CityzenUNDEAD, ну вот значит через union вполне можно.
    А зачем вообще нужно данные отсортировать так?
  • Василий Банников,

    А зачем вообще нужно данные отсортировать так?

    numbers это список айдишников для связанной таблицы которая связана с Records. Это таблица указывает на категорию отдельно взятой записи в таблице Records.
    И задача в том что мне нужно отправить на фронт записи Records в порядке их приоритетов. Но проблема в том, что эта самая таблица где указаны id приоритетов все идет не по порядку. Наивысший приоритет это запись у которой нет ссылок на родительскую записи, и дальше по убыванию.

  • Василий Банников, похоже, автор вопроса пытается дальше решать свою предыдущую задачу. К сожалению, он ее целиком не огласил, потому только после этого вопроса, увидев в нем IQueriable, я осознал, что ему надо эту задачу решить для данных из БД, и это меняет дело - у многих БД есть для этого специальный механизм - recursive CTE. И это я написал в том запросе.
    Другое дело, что EF с LINQ, через которые он, кажется (но это неточно - автор скуп на подробности) пытается решать задачу, средсдств для использования recursive CTE, кажется, не предоставляют, и нужно писать и как-то подключать SQL-запрос самому.
  • CityzenUNDEAD, см. мой предыдущий комментарий плюс мой свежий ответ к вашему предыдущему вопросу.
    Это, конечно, не ответ, но, надеюсь, это наведет вас на решение.
  • MVV, спасибо за комментарий. Да, задача разделилась не несколько подзадач. Про сортировку на уровне бд не писал ранее т.к. предполагалось что там проблем не возникнет. Но этот момент я не предвидел.
    Я сейчас пришёл к выводу, что наверное проще и лучше изменить структуру бд. Добавить новую таблицу справочник, вместо того что бы записи одной таблицы указывали друг на друга.
  • Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Игорь Волков Ответ

    Проблема, с которой вы столкнулись, связана с тем, что интерфейс IQueryable не предоставляет методов сортировки данных напрямую. Однако, вы можете использовать метод OrderBy или OrderByDescending из LINQ для выполнения сортировки данных, прежде чем выполнить запрос к базе данных.

    Давайте рассмотрим пример на языке программирования C# с использованием LINQ для сортировки данных в IQueryable:

    using System;
    using System.Linq;
     
    class Program
    {
        static void Main()
        {
            // Создание объекта контекста базы данных
            YourDbContext dbContext = new YourDbContext();
     
            // Получение IQueryable объекта
            IQueryable query = dbContext.YourEntities;
     
            // Выполнение сортировки по полю Name
            query = query.OrderBy(e => e.Name);
     
            // Выполнение запроса
            var result = query.ToList();
     
            // Вывод отсортированных данных
            foreach (var entity in result)
            {
                Console.WriteLine(entity.Name);
            }
        }
    }

    using System; using System.Linq; class Program { static void Main() { // Создание объекта контекста базы данных YourDbContext dbContext = new YourDbContext(); // Получение IQueryable объекта IQueryable query = dbContext.YourEntities; // Выполнение сортировки по полю Name query = query.OrderBy(e => e.Name); // Выполнение запроса var result = query.ToList(); // Вывод отсортированных данных foreach (var entity in result) { Console.WriteLine(entity.Name); } } }

    В данном примере мы создаем объект контекста базы данных и получаем IQueryable объект. Затем мы используем метод OrderBy для сортировки данных по полю Name. Наконец, мы выполняем запрос и выводим отсортированные данные.

    Убедитесь, что вы добавили using System.Linq; в начале вашего файла, чтобы иметь доступ к методам LINQ. Также убедитесь, что ваша сущность имеет свойство Name, которое вы можете использовать для сортировки.

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

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно