EF Core 2.1 оценивает локально, когда подзапрос и агрегат после группировки

2
задан GingerTez 13 July 2018 в 09:53
поделиться

2 ответа

Следующее правило состоит в том, чтобы избежать Where и предикатной версии Count в GroupBy результате и, если это возможно, использовать условный Sum. EF6 удалось перевести такие конструкции, но с очень неэффективным SQL.

Итак, в общем случае вам нужно переписать запрос следующим образом:

data
    .GroupBy(i => new { i.Status, i.InvoiceType })
    .Select(g => new
    {
        g.Key,
        Count = g.Count(),
        TotalLessThan100 = g.Sum(i => i.InvoicePayments < 100 ? i.EligibleValue : 0),
        TotalLessThan500 = g.Sum(i => i.InvoicePayments < 500 ? i.EligibleValue : 0)
    });

Однако EF Core 2.1 GroupBy улучшения перевода не включают Sum с другим, чем простой селектор свойств, поэтому вышеупомянутое все еще использует оценку клиента. Скорее всего, он будет исправлен в какой-то будущей версии, но до тех пор может использовать следующий трюк: добавить промежуточную проекцию (Select) до GroupBy, содержащую все поля, необходимые позже, включая рассчитанные, а затем использовать их внутри агрегаты после GroupBy:

data
    .Select(i => new
    {
        i.Status,
        i.InvoiceType,
        LessThan100 = i.InvoicePayments < 100 ? i.EligibleValue : 0,
        LessThan500 = i.InvoicePayments < 500 ? i.EligibleValue : 0,
    })
    .GroupBy(i => new { i.Status, i.InvoiceType })
    .Select(g => new
    {
        g.Key,
        Count = g.Count(),
        TotalLessThan100 = g.Sum(i => i.LessThan100),
        TotalLessThan500 = g.Sum(i => i.LessThan500)
    });

, который переводится на:

SELECT [i].[Status], [i].[InvoiceType], COUNT(*) AS [Count], SUM(CASE
    WHEN [i].[InvoicePayments] < 100.0
    THEN [i].[EligibleValue] ELSE 0.0
END) AS [TotalLessThan100], SUM(CASE
    WHEN [i].[InvoicePayments] < 500.0
    THEN [i].[EligibleValue] ELSE 0.0
END) AS [TotalLessThan500]
FROM [Invoice] AS [i]
GROUP BY [i].[Status], [i].[InvoiceType]
5
ответ дан Ivan Stoev 17 August 2018 в 13:16
поделиться

https://blogs.msdn.microsoft.com/dotnet/2018/05/30/announcing-entity-framework-core-2-1/

" Теперь мы поддерживаем перевод его в предложение SQL GROUP BY в большинстве распространенных случаев. "

Предположительно, ваш случай не является« общим »?

У меня была эта проблема в версии 2.0. Я решил это, вручную разработав множество методов для генерации SQL. да, это был PITA, но я хотел придерживаться Core по другим причинам.

0
ответ дан GPW 17 August 2018 в 13:16
поделиться
  • 1
    Я предполагаю, что «обычные случаи» это вопрос мнения ;-) Я не уверен, что мы хотим идти по пути ручного перевода перевода GroupBy на SQL-высказывания (хотя спасибо за предложение). – GingerTez 13 July 2018 в 10:07
Другие вопросы по тегам:

Похожие вопросы: