Как преобразовать Group by в LINQ

Добрый день. Я работаю над веб-приложением 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

Идентификатор ОбъектОтветственный Позиция Положение дел NextEntityResponsible Следующая позиция СтатусДата вступления в силу TatCount CrmdId 1 Инициалы - Для обзора Образец Аналитик 2022-11-21 0 1 2 Образец Аналитик Вернулся Ветка - 2022-11-21 0 1

Может ли кто-нибудь помочь мне или научить меня, что не так в моем коде. Спасибо!

Рабочий код:

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" );

Вышеупомянутое даже компилируется? .GroupBy() вернет объект IEnumerable<IGrouping<TKey,TSource>>, но IGrouping<> не имеет свойства Id. Я ожидаю, что .OrderByDescending( x => x.Id ) выдаст ошибку времени компиляции. IGrouping<> имеет свойство Key. Это то, что вы намеревались?

T N 21.11.2022 04:10

Да, .OrderByDescending(x => x.Id) не компилируется и получает указанную вами ошибку, но приведенный выше код представляет собой синтаксис или запрос, который я хочу отобразить.

Jimy 21.11.2022 04:21

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

Jimy 21.11.2022 04:24

CrmId имеет разные статусы/идентификаторы, и я хочу сгруппировать данные по его CrmId и отображать только последнее значение, поэтому я использовал GroupBy и orderbydescending, но это не работает

Jimy 21.11.2022 04:31

Прежде чем мы сможем вам помочь, нам нужна дополнительная информация: (1) Структура вашего источника Tats (поля и типы данных). (2) Пример данных. (3) Структура вашего класса PerAnalystReportDto. Ожидаемые результаты. Если можете, упростите данные до минимума, необходимого для демонстрации вашей проблемы. Например, включите CrmId, Id и, возможно, один или два других элемента данных.

T N 21.11.2022 04:37

Привет @TN, я отредактирую вопрос и опубликую скриншот и свои коды. Спасибо

Jimy 21.11.2022 04:39

Кроме того, уточните, что вы подразумеваете под «отображать только последнее значение». Будут ли данные содержать несколько записей с одинаковыми значениями CrmId, но разными значениями Id? Вы намерены отфильтровать все записи, кроме одной, для каждого значения CrmId? Определяется ли «последний» максимальным значением Id (а не чем-то вроде Report Date)?

T N 21.11.2022 04:42

«Будут ли данные содержать несколько записей с одинаковыми значениями CrmId, но разными значениями Id?» -Да, данные содержат несколько записей с одинаковым CrmId, но с разными идентификаторами. «Вы намерены отфильтровать все записи, кроме одной, для каждого значения CrmId? «Последняя» определяется наивысшим значением идентификатора (а не чем-то вроде даты отчета)?» -Да, я хочу отфильтровать все записи, кроме одной, для каждого CrmId, но с самым высоким значением идентификатора.

Jimy 21.11.2022 04:47

Пожалуйста, размещайте удобочитаемые данные вместо снимков экрана, желательно в виде таблицы или блока кода. (Если у вас возникли проблемы с форматированием, опубликуйте все, что можете, и кто-нибудь может помочь настроить макет.)

T N 21.11.2022 04:49

Привет, @TN уже отредактировала сообщение, а также добавила таблицу для образцов данных о татуировках.

Jimy 21.11.2022 05:12
Руководство для начинающих по веб-разработке на React.js
Руководство для начинающих по веб-разработке на React.js
Веб-разработка - это захватывающая и постоянно меняющаяся область, которая постоянно развивается благодаря новым технологиям и тенденциям. Одним из...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
0
10
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, насколько я понимаю, вам нужен набор результатов, который включает верхнее значение 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, сначала я хочу поблагодарить вас за руководство и помощь в этой проблеме, код скомпилировался, но не отображал никаких данных в таблице, как на втором скриншоте таблицы выше.

Jimy 21.11.2022 06:10

Пришло время погрузиться в отладчик, чтобы проверить значение perAnalystReport перед его сериализацией. Это должно быть List из PerAnalystReportDto объектов, содержащих выбранные данные. Если все в порядке, возможно, проблема связана с определением отчета. Возможно, более ранняя версия кода предоставляла отчету вложенную структуру коллекции, и он все еще ожидает этого. Один из способов подтвердить это — заменить .First() на .Take(1). Это снова создаст вложенную коллекцию, и отчет может отображать нужные данные. Это будет только клуге, а не исправление.

T N 21.11.2022 07:07

Привет @TN Я начал отлаживать код и получил такой результат: $exception [InvalidOperationException]: {System.InvalidOperationException}: выражение LINQ 'GroupByShaperExpression': Keyselector и т. д.

Jimy 21.11.2022 09:23

Привет @TN, я немного изменил код, и это сработало. Спасибо за любезное руководство. Я также опубликую код, который работает для меня.

Jimy 21.11.2022 10:27

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