Resumo : neste tutorial, você aprenderá como usar o GroupBy()
método LINQ para agrupar linhas em grupos e aplicar uma função agregada a cada grupo no EF Core.
Introdução ao EF Core GroupBy
Às vezes, você deseja agrupar linhas em grupos e aplicar funções de agregação como contagem, máximo, mínimo, média e soma a cada grupo.
Por exemplo, você pode querer agrupar funcionários por departamentos e contar o número de funcionários de cada um:
Para fazer isso, você pode usar o LINQ GroupBy()
e Count()
métodos como este:
using static System.Console;
using HR;
using var context = new HRContext();
var groups = context.Employees
.GroupBy(e => e.Department)
.Select(group => new
{
DepartmentName = group.Key.Name,
Headcount = group.Count()
})
.OrderBy(dc => dc.DepartmentName)
.ToList();
foreach (var group in groups)
{
WriteLine($"{group.DepartmentName,-20}{group.Headcount}");
}
Linguagem de código: C# ( cs )
Saída:
Engineering 11
Finance 13
Marketing 13
Operations 11
Sales 12
Linguagem de código: texto simples ( texto simples )
Como funciona.
Primeiro, o GroupBy()
método agrupa funcionários por departamentos e retorna uma coleção de IGrouping<TKey, TElement>
objetos. Cada objeto de agrupamento possui duas propriedades: a chave é o departamento e o elemento é uma coleção de funcionários que pertencem a esse departamento:
Sales
- John Doe
- Emily Brown
...
Marketing
- Jane Smith
- William Taylor
- Daniel Clark
...
Linguagem de código: texto simples ( texto simples )
Segundo, o Select()
método cria um objeto anônimo com duas propriedades DepartmentName
e Headcount. Atribui a propriedade Nome do objeto Departamento ao DepartmentName
e o número de funcionários por grupo à propriedade Headcount:
Sales 12
Marketing 13
...
Linguagem de código: texto simples ( texto simples )
Terceiro, o OrderBy()
método classifica os grupos por DepartmentName
.
Finalmente, o ToList()
método executa a consulta e retorna o resultado.
O EF Core gera a seguinte instrução SQL que usa a GROUP BY
cláusula para agrupar funcionários por departamentos e aplica uma COUNT
função agregada a cada grupo:
SELECT
[d].[Name] AS [DepartmentName],
COUNT(*) AS [Headcount]
FROM
[Employees] AS [e]
INNER JOIN [Departments] AS [d] ON [e].[DepartmentId] = [d].[Id]
GROUP BY
[d].[Id],
[d].[Name]
ORDER BY
[d].[Name]
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Para aplicar uma condição a cada grupo, você usa o Where()
método LINQ. Por exemplo, o seguinte seleciona departamentos que têm mais de 11 funcionários:
using static System.Console;
using HR;
using var context = new HRContext();
var groups = context.Employees
.GroupBy(e => e.Department)
.Select(group => new
{
DepartmentName = group.Key.Name,
Headcount = group.Count()
})
.Where(group => group.Headcount > 11)
.OrderBy(dc => dc.DepartmentName)
.ToList();
foreach (var group in groups)
{
WriteLine($"{group.DepartmentName,-20}{group.Headcount}");
}
Linguagem de código: C# ( cs )
Saída:
Finance 13
Marketing 13
Sales 12
Linguagem de código: texto simples ( texto simples )
Neste exemplo, o EF Core gera uma instrução SQL que usa uma GROUP BY
cláusula com uma HAVING
cláusula:
SELECT
[d].[Name] AS [DepartmentName],
COUNT(*) AS [Headcount]
FROM
[Employees] AS [e]
INNER JOIN [Departments] AS [d] ON [e].[DepartmentId] = [d].[Id]
GROUP BY
[d].[Id],
[d].[Name]
HAVING
COUNT(*) > 11
ORDER BY
[d].[Name]
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Resumo
- Use o método LINQ
GroupBy()
para formar uma consulta que use aGROUP BY
cláusula para agrupar linhas em grupos.