Grupo principal EF por

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               12Linguagem 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 DepartmentNamee Headcount. Atribui a propriedade Nome do objeto Departamento ao DepartmentNamee 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 BYcláusula para agrupar funcionários por departamentos e aplica uma COUNTfunçã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               12Linguagem de código:  texto simples  ( texto simples )

Neste exemplo, o EF Core gera uma instrução SQL que usa uma GROUP BYcláusula com uma HAVINGclá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 a GROUP BYcláusula para agrupar linhas em grupos.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *