Добрый день. Я работаю над веб-приложением Asp.net core ef и в настоящее время делаю отчеты с использованием LINQ, но при группировке по идентификатору он не работает или ничего не отображает, на 1-м снимке экрана ниже показана таблица, когда я пишу только Orderbydescending и 2-й скриншот - это таблица, когда я пишу Group By.
public async Task<ContentResult> GetReportData() {
var perAnalystReport = await _context.Tats
.ProjectTo<PerAnalystReportDto( _mapper.ConfigurationProvider )
.GroupBy (x => x.CrmId )
.OrderByDescending( x => x.Id )
.ToListAsync();
return Content( JsonConvert.SerializeObject( perAnalystReport ), "application/json" );
}
Класс PerAnalystReporDto
public string RefNo { get; set; }
public int CrmId { get; set; }
public DateTime? ReportDate { get; set; }
public DateTime? HoReceivedDate { get; set; }
public string ApprovingAuthorityName { get; set; }
public string BranchName { get; set; }
public string AreaName { get; set; }
public string RegionName { get; set; }
public string Analyst { get; set; }
public string AccountName { get; set; }
public string RequestName { get; set; }
public string FacilityName { get; set; }
public string Description { get; set; }
public string CurrencyName { get; set; }
public int AmountFrom { get; set; }
public int AmountTo { get; set; }
public string Status { get; set; }
public string NextEntityResponsible {get; set;}
public string Remarks { get; set; }
public string Position { get; set; }
public DateTime StatusEffectiveDate { get; set; }
public int TatCount { get; set; }
public int Id {get; set;}
Образец данных Tat
Может ли кто-нибудь помочь мне или научить меня, что не так в моем коде. Спасибо!
Рабочий код:
public ContentResult GetReportData() {
var perAnalystReport = _context.Tats
.ProjectTo<PerAnalystReportDto( _mapper.ConfigurationProvider )
.ToList()
.GroupBy (x => x.CrmId )
.Select(g => g.OrderByDescending( x => x.Id ).First())
.ToList();
return Content( JsonConvert.SerializeObject( perAnalystReport ), "application/json" );
Да, .OrderByDescending(x => x.Id) не компилируется и получает указанную вами ошибку, но приведенный выше код представляет собой синтаксис или запрос, который я хочу отобразить.
Но когда я использую только порядок по убыванию, код компилируется и отображается 1-й снимок экрана выше
CrmId имеет разные статусы/идентификаторы, и я хочу сгруппировать данные по его CrmId и отображать только последнее значение, поэтому я использовал GroupBy и orderbydescending, но это не работает
Прежде чем мы сможем вам помочь, нам нужна дополнительная информация: (1) Структура вашего источника Tats (поля и типы данных). (2) Пример данных. (3) Структура вашего класса PerAnalystReportDto. Ожидаемые результаты. Если можете, упростите данные до минимума, необходимого для демонстрации вашей проблемы. Например, включите CrmId, Id и, возможно, один или два других элемента данных.
Привет @TN, я отредактирую вопрос и опубликую скриншот и свои коды. Спасибо
Кроме того, уточните, что вы подразумеваете под «отображать только последнее значение». Будут ли данные содержать несколько записей с одинаковыми значениями CrmId, но разными значениями Id? Вы намерены отфильтровать все записи, кроме одной, для каждого значения CrmId? Определяется ли «последний» максимальным значением Id (а не чем-то вроде Report Date)?
«Будут ли данные содержать несколько записей с одинаковыми значениями CrmId, но разными значениями Id?» -Да, данные содержат несколько записей с одинаковым CrmId, но с разными идентификаторами. «Вы намерены отфильтровать все записи, кроме одной, для каждого значения CrmId? «Последняя» определяется наивысшим значением идентификатора (а не чем-то вроде даты отчета)?» -Да, я хочу отфильтровать все записи, кроме одной, для каждого CrmId, но с самым высоким значением идентификатора.
Пожалуйста, размещайте удобочитаемые данные вместо снимков экрана, желательно в виде таблицы или блока кода. (Если у вас возникли проблемы с форматированием, опубликуйте все, что можете, и кто-нибудь может помочь настроить макет.)
Привет, @TN уже отредактировала сообщение, а также добавила таблицу для образцов данных о татуировках.
Итак, насколько я понимаю, вам нужен набор результатов, который включает верхнее значение Id для каждого CrmId. Вы были на правильном пути, но вам нужно было применить OrderByDescending() к каждой группе, а затем выбрать только самого последнего (первого) из упорядоченных членов группы.
Я считаю, что следующее должно дать вам то, что вы ищете:
var perAnalystReport = await _context.Tats
.ProjectTo<PerAnalystReportDto>(_mapper.ConfigurationProvider)
.GroupBy(x => x.CrmId )
.Select(g => g.OrderByDescending(x => x.Id).First())
.ToListAsync();
Или, возможно, с немного лучшей производительностью:
var perAnalystReport = await _context.Tats
.GroupBy(x => x.CrmId )
.Select(g => g.OrderByDescending(x => x.Id).First())
.ProjectTo<PerAnalystReportDto>(_mapper.ConfigurationProvider)
.ToListAsync();
Последнее позволяет избежать создания объектов PerAnalystReportDto для исключаемых записей.
Для предоставленных ограниченных выборочных данных это должно дать только запись Id = 2 для группы CrmdId = 1.
Привет @TN, сначала я хочу поблагодарить вас за руководство и помощь в этой проблеме, код скомпилировался, но не отображал никаких данных в таблице, как на втором скриншоте таблицы выше.
Пришло время погрузиться в отладчик, чтобы проверить значение perAnalystReport перед его сериализацией. Это должно быть List из PerAnalystReportDto объектов, содержащих выбранные данные. Если все в порядке, возможно, проблема связана с определением отчета. Возможно, более ранняя версия кода предоставляла отчету вложенную структуру коллекции, и он все еще ожидает этого. Один из способов подтвердить это — заменить .First() на .Take(1). Это снова создаст вложенную коллекцию, и отчет может отображать нужные данные. Это будет только клуге, а не исправление.
Привет @TN Я начал отлаживать код и получил такой результат: $exception [InvalidOperationException]: {System.InvalidOperationException}: выражение LINQ 'GroupByShaperExpression': Keyselector и т. д.
Привет @TN, я немного изменил код, и это сработало. Спасибо за любезное руководство. Я также опубликую код, который работает для меня.
Вышеупомянутое даже компилируется? .GroupBy() вернет объект IEnumerable<IGrouping<TKey,TSource>>, но IGrouping<> не имеет свойства Id. Я ожидаю, что .OrderByDescending( x => x.Id ) выдаст ошибку времени компиляции. IGrouping<> имеет свойство Key. Это то, что вы намеревались?