IQueryable <T> дает отличный результат, чем List <T>

Если я использую Select on IQueryable в моем представлении фрейма сущности, я получу 4 элемента.

Если я использую Select на IQueryable.ToList(), я получаю все 36 элементов.

Здесь код функции:

public ImagesGetModelView Get(int start, int count)
{
    if (count <= 0) count = 9;
    else if (count > ImageHandler.MaxResult) count = ImageHandler.MaxResult;    

        IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count)
           .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat);

        //Works using list :(
        //var list = imagesList.ToList();

        //Select all subreddits once
        //Returns 4 instead of 36 if not using the list ...
        //Returns 1 instead of 2 with Distinct() if not using the list
        IEnumerable<Subreddit> subreddits = imagesList
           .Select(m => m.Subreddit); //.Distinct();           

        ImagesGetModelView result = new ImagesGetModelView()
        {
            Items = imagesList,
            Subreddits = subreddits
        };

        return result;
    } 

public IQueryable<Image> FetchRangeScore(int a_start, int a_count)
    {
        return Repository.AllQueryable().OrderByDescending(m => m.Score)
          .Skip(a_start).Take(a_count);
    }

Из 36 предметов 2 Субреддиты будут отличаться. Но поскольку только 4 из 36 выбраны из Select(), он находит только 1 отдельный.

Итак, есть ли что-нибудь, что я могу сделать с выражениями LINQ, чтобы получить правильные данные, чтобы работать с отдельным оператором, или мне нужно сделать это в List, прежде чем продолжить с помощью функций Select и Distinct?

Edit:
переместив место подачи заявки от конца до начала всего запроса. Кажется, он работает правильно. Select возвращает все 36 элементов e.t.c..., что, в свою очередь, делает работу Distinct, так как она может найти более 1 уникального значения.

 public IQueryable<Image> FetchRangeScore(int a_start, int a_count)
    {
        return Repository.AllQueryable()
          .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat)
          .OrderByDescending(m => m.Score)
          .Skip(a_start).Take(a_count);
    }

Ответ 1

Скорее всего, ваше предложение Where ведет себя по-другому в SQL Server, чем в .NET. В частности, в зависимости от настроек сортировки и т.д., Вероятно, что различные значения .Domain отличаются только капитализацией или чем-то подобным, что делает их "равными" для Gfycat в SQL, но не в С#.

Вы можете записать .ToString() на свой IQueryable<>, чтобы узнать, что SQL создается и попробовать самостоятельно.

IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count)
   .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat);
Debug.WriteLine(imagesList.ToString());

Ответ 2

Трудно быть уверенным без исходных данных, но Distinct работает по-разному при нажатии на SQL.

Запрос SQL Distinct будет вызывать записи, где все значения различны. Когда вы выполняете вызов Distinct в списке объектов в памяти, по умолчанию он будет использовать равенство экземпляра. Таким образом, вы можете вернуть "дублированные" объекты (объекты, где все значения полей одинаковы), но они будут разными "экземплярами", поэтому Distinct рассматривает их как разные объекты.

Таким образом, это зависит от того, что вы хотите - вы хотите, чтобы все значения Subreddit, включая дубликаты, или вам нужны разные значения?

Чтобы ответить на ваш вопрос: если вы не хотите, чтобы вызов Distinct передавался в SQL, вы можете вызвать AsEnumerable() вместо ToList, что делает все дальнейшие запросы Linq Linq-to-Objects (IEnumerable<T>) вместо запросов Linq-to-{whatever} (IQueryable<T>) без накладных расходов на размещение элементов в списке.