EF Core 2.1 - SQL Join com LINQ - II


 Neste artigo veremos como realizar consultas SQL Join com LINQ usando o Entity Framework Core 2.1.

Continuando a primeira parte do artigo vamos aplicar agora as consultas SQL Join usando o LINQ com Entity Framework Core 2.0.

Vamos usar a cláusula join que é útil para associar elementos de sequências de origem diferentes que não têm nenhuma relação direta no modelo de objeto.

O único requisito é que os elementos em cada fonte compartilhem algum valor que possa ser comparado pela igualdade.

Uma cláusula join recebe duas sequências de origem como entrada. Os elementos em cada sequência devem ser ou conter uma propriedade que possa ser comparada com uma propriedade correspondente na outra sequência. A cláusula join compara a igualdade das chaves especificadas, usando a palavra-chave especial equals.

Todas as junções realizadas pela cláusula join são junções por igualdade. A forma da saída de uma cláusula join depende do tipo específico de junção que você está realizando.

Para isso vamos usar o projeto EFCore_Joins  criado no artigo anterior.

1 - Aplicando o Inner Join ou junção interna

Um inner join ou a junção interna retorna apenas os registros que existem nas tabelas.

Usando a palavra-chave "join", podemos fazer uma junção interna usando uma consulta LINQ.

A instrução SQL gerada pelo EF Core foi a seguinte :

SELECT [f].[FuncionarioNome] AS [Nome], [f].[FuncionarioCargo] AS [Cargo], [s].[SetorNome] AS [Setor]
FROM [Funcionarios] AS [f]
INNER JOIN [Setores] AS [s] ON [f].[SetorId] = [s].[SetorId]

2 - Aplicando o Left Outer Join ou junção externa à esquerda

Um Left Outer Join retorna todos os registros da tabela à esquerda e o registro correspondente da tabela à direita.

Se não houver registros correspondentes na tabela correta, ele retornará null.

Se quisermos fazer uma junção Left Outer no LINQ, devemos usar a palavra-chave "into" e o método "DefaultIfEmpty".

A instrução SQL gerada pelo EF Core foi a seguinte  :

SELECT [f].[FuncionarioNome] AS [Nome], [f].[FuncionarioCargo] AS [Cargo], [s].[SetorNome] AS [Setor]
FROM [Funcionarios] AS [f]
LEFT JOIN [Setores] AS [s] ON [f].[SetorId] = [s].[SetorId]

Vemos na consulta a palavra-chave LEFT JOIN que etorna todos os registros da tabela à esquerda (Funcionarios) e os registros correspondentes da tabela à direita (Setores).

O resultado é NULL do lado direito, se não houver correspondência.

3 - Aplicando o Rigth Outer Join ou junção externa à direita

A LINQ  não suporta um Rigth Outer Join ou junção externa á direita.

Para contornar essa limitação podemos trocar as tabelas e fazer um Left Outer Join e teremos o comportamento esperado para o Right Outer Join.

A instrução SQL gerada pelo EF Core foi a seguinte  :

 SELECT [f].[FuncionarioNome] AS [Nome], [f].[FuncionarioCargo] AS [Cargo], [s].[SetorNome] AS [Setor]
FROM [Setores] AS [s]
LEFT JOIN [Funcionarios] AS [f] ON [s].[SetorId] = [f].[SetorId]

4 - Aplicando Full Outer Join ou junção externa completa

Um Full Outer Join ou junção externa completa é uma união lógica de uma junção externa esquerda e uma junção externa direita.

O LINQ não suporta junções externas completas diretamente da mesma forma que as junções externas à direta.

O que podemos fazer e juntar um Left e Rigth Outer Join e usar o método Union para encontrar os elementos exclusivos entre duas sequências ou coleções.

O método Union é um método de extensão usado para mesclar duas coleções sendo que a coleção mesclada contém apenas os elementos distintos de ambas as coleções.

using EFCore_Joins.Models;
using System;
using System.Linq;
namespace EFCore_Joins
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var contexto = new AppDbContext())
            {
                var leftOuterJoin = from f in contexto.Funcionarios
                                    join s in contexto.Setores on f.SetorId equals s.SetorId into set
                                    from setor in set.DefaultIfEmpty()
                                    select new
                                    {
                                        Nome = f.FuncionarioNome,
                                        Cargo = f.FuncionarioCargo,
                                        Setor = setor.SetorNome
                                    };
                var rightOuterJoin = from s in contexto.Setores
                                     join f in contexto.Funcionarios on s.SetorId equals f.SetorId into funci
                                     from funcionario in funci.DefaultIfEmpty()
                                     select new
                                     {
                                         Nome = funcionario.FuncionarioNome,
                                         Cargo = funcionario.FuncionarioCargo,
                                         Setor = s.SetorNome
                                     };
                leftOuterJoin = leftOuterJoin.Union(rightOuterJoin);
                Console.WriteLine("Funcionario\t\tCargo\t\tSetor");
                foreach (var resultado in leftOuterJoin)
                {
                    if (!string.IsNullOrEmpty(resultado .Nome))
                        Console.WriteLine(resultado .Nome + "\t\t" + resultado .Cargo + "\t" + resultado .Setor);
                    else
                        Console.WriteLine(resultado .Nome + "\t\t" + resultado .Cargo + "\t\t" + resultado .Setor);
                }
            }
            Console.ReadLine();
        }
}

Na próxima parte do artigo veremos as SQL Join restantes...

"Ora, àquele que é poderoso para vos guardar de tropeçar, e apresentar-vos irrepreensíveis, com alegria, perante a sua glória,
Ao único Deus sábio, Salvador nosso, seja glória e majestade, domínio e poder, agora, e para todo o sempre. Amém."

Judas 1:24,25

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti