Следующее правило состоит в том, чтобы избежать 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]
https://blogs.msdn.microsoft.com/dotnet/2018/05/30/announcing-entity-framework-core-2-1/
" Теперь мы поддерживаем перевод его в предложение SQL GROUP BY в большинстве распространенных случаев. "
Предположительно, ваш случай не является« общим »?
У меня была эта проблема в версии 2.0. Я решил это, вручную разработав множество методов для генерации SQL. да, это был PITA, но я хотел придерживаться Core по другим причинам.
GroupBy
на SQL-высказывания (хотя спасибо за предложение).
– GingerTez
13 July 2018 в 10:07