Как выполнить запрос в ядре EF с помощью OrderByDescending, Take, Select и FirstOrDefault - PullRequest
0 голосов
/ 22 марта 2020

Итак, у меня есть таблица с именем Summaries, она выглядит так по ServiceCode и запрашивается по месяцам, например, ServiceCode 'A' имеет записи на 2020-01-01, 2020-01-02, 2020-01-03, 2020-01-31, 2020-02-01, 2020-02- 28, 2020-02-29 и ServiceCode 'B' имеет записи на 2020-01-01, 2020-01-02, 2020-01-31, 2020-02-20, 2020-02-21, мне нужно получить сумма, основанная на месяце, последняя запись в 'A' в январе - 2020-01-31, а в 'B' последняя запись в 2020-01-31, мне нужно сложить их 'TotalPieces', поэтому я должен получить 25 + 25 = 50.

В основном мне нужно сделать это

  • Получить все последние записи на основе CoveredDate и месяц / год
  • Сумма TotalPieces на ServiceCode

я получил рабочий запрос, но это всего лишь обходной путь, потому что я не могу получить его правильно по запросу.

            int sum_totalpieces = 0;
            foreach (var serviceCode in service_codes)
            {
                var totalpieces = _DbContext.ActiveSummaries.Where(acs =>
                                    acs.CoveredDate.Date.Month == query_month
                                    && acs.CoveredDate.Date.Year == query_year
                                    && acs.service_codes == serviceCode
                                    )
                    .OrderByDescending(obd => obd.CoveredDate)
                    .Take(1)
                    .Select(s => s.TotalPieces)
                    .ToList()
                    .FirstOrDefault();

                sum_totalpieces += totalpieces;
            }

service_codes просто список строк

Если бы вы, ребята, могли просто получить избавьтесь от foreach блокирования их и сделайте его services_codes.Contains() по запросу, или другой обходной путь, чтобы сделать результат быстрее, что было бы здорово. Большое спасибо.

1 Ответ

1 голос
/ 22 марта 2020

Это будет сделано, но я не думаю, что оно будет переводиться на SQL и работать на сервере:

    _DbContext.ActiveSummaries
            .Where(b =>
                b.CoveredDate >= new DateTime(2020,1,1) &&
                b.CoveredDate < new DateTime(2020,2,1) && 
                new [] { "A", "B" }.Contains(b.ServiceCode)
            )
            .GroupBy(g => g.ServiceCode)
            .Sum(g => g.OrderByDescending(gb=> gb.CoveredDate).First().TotalPieces);


Если вы хотите сделать это как необработанный SQL для лучшего производительность это будет выглядеть так:

SELECT SUM(totalpieces)
FROM 
  x 
  INNER JOIN 
  (
    SELECT servicecode, MAX(covereddate) cd 
    FROM x 
    WHERE x.servicecode IN ('A','B') AND covereddate BETWEEN '2020-01-01' AND '2020-01-31'
  )y ON x.servicecode=y.servicecode and x.covereddate = y.cd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...