Как преобразовать IQueryable в список для отображения возвращаемых данных?

#c# #asp.net #asp.net-core

Вопрос:

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

 public async Task<ResultData<HomePlannedRecieptInfo>> GetHomePlannedReciepts(HomePlannedRecieptQuery query)
{
    var datelist = new List<DateTime>();
    var date = DateTime.Now;
    for (var i = 0; i <= 6; i  )
    {
        datelist.Add(date.AddDays(i));
    }
    datelist.Add(date);

    IQueryable<HomePlannedRecieptInfo> result = context.HomePlannedRecieptInfos.Where(t=>t.Date >= DateTime.Today);
      
    foreach (var item in result.ToList())
    {
        item.DayDiff = (item.Date.Date - DateTime.Now.Date).TotalDays.ToString();
    }

    var offset = (query.PageNumber - 1) * query.PageSize;
    var psize = query.PageSize;
    var countQuery = await result.CountAsync();
    var data = result.OrderByDescending(c => c.Date);

    return new ResultData<HomePlannedRecieptInfo>
    {
        CurrentPage = query.PageNumber,
        TotalItems = countQuery,
        PageSize = query.PageSize,
        Data = data.ToList()
    };
 

когда я выполняю код в foreach, я вижу количество дней в файле item.dayDiff, но я не вижу его при возврате данных. Кто-нибудь может мне помочь, пожалуйста?

Ответ №1:

Ты называешь результат.ToList(), но вы просто повторяете его в цикле foreach, на самом деле вы нигде его не храните. Это должно все исправить:

    var resultAsList = result.ToList();
   foreach (var item in resultAsList)
    {
        item.DayDiff = (item.Date.Date - DateTime.Now.Date).TotalDays.ToString();
    }


    ...
    var data = resultAsList.OrderByDescending(c => c.Date);
 

Ответ №2:

Это связано с тем, что каждый раз, когда вы материализуете IQueryable, данные берутся из базы данных. Вы дважды материализуетесь в своем коде. Один раз в foreach и один раз при возврате данных в data.ТоЛист(). Следовательно, у вас есть два списка с разными элементами. Поскольку вы изменяете данные в первом списке, второй не получит эти данные.

У вас есть две возможности:

  • Вызовите ToList перед foreach и используйте тот же материализованный список для изменения свойства и возврата того же списка
  • Измените параметр get acessor для DayDiff на следующий public string DayDiff {get => (Date.Date - DateTime.Now.Date).TotalDays.ToString();} , используя это преимущество в том, что вам не нужно напоминать о необходимости установки DayDiff, если вы запрашиваете данные в других местах вашего кода