Banco de Dados

11 out, 2018

EF Core – Logando os comandos SQL no console

Publicidade

Hoje vou mostrar como podemos logar e exibir as consultaas SQL geradas pelo EF Core no console. Quando você usa uma ferramenta OR/M como o EF Core, você está incluindo mais uma camada de abstração na sua aplicação.

Por trás dos panos o EF Core vai interpretar as consultas LINQs usadas na sua aplicação e, de acordo com o mapeamento das entidades e seus relacionamentos, vai gerar o comando SQL adequado para realizar a operação desejada no banco de dados.

De forma geral, para a maioria dos cenários, o EF Core faz um bom trabalho e gera consultas SQL otimizadas com base nas consultas LINQ.

Ocorre que existem situações nas quais você vai precisar otimizar a consulta SQL gerada e para fazer isso você tem que obter e analisar a consulta gerada pelo EF Core.

Então vou mostrar uma forma bem simples de exibir as consultas SQL geradas pelo EF Core no console.

Recursos usados

Criando o projeto Console

Abra o VS 2017 Community e crie um novo projeto usando o template .NET Core > Console App(.NET Core) com o nome EFCore_LogSQL.

Vamos instalar os seguintes pacotes:

Microsoft.EntityFrameworkCore.SqlServer: com isso instalaremos o EF Core para usar o SQL Server e também instalar todas as dependências que precisamos para trabalhar com o EF Core no SQL Server. Se voce quiser trabalhar com outro banco de dados, veja a lista de provedores neste link.

  • Ou: install-package Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools: este pacote vai permitir usar uma interface de linha de comandos (CLI) para poder realizar tarefas com o EF Core.

  • Ou: install-package Microsoft.EntityFrameworkCore.Tools

Microsoft.Extensions.Logging.Console: para poder logar as consultas SQL geradas pelo EF Core no Console.

Ao final, seu projeto deverá conter as referências aos pacotes acima.

Agora já podemos acessar o SQL Server, usar o Migrations e usar os recursos do Lazy Loading no EF Core.

Criando o modelo de domínio e a classe de contexto

Crie uma pasta Models no projeto e a seguir, como exemplo, vamos criar um modelo de entidades contendo duas classes com uma associação um-para-muitos:

Autor e Livro onde um autor pode ter muitos livros:

Agora vamos criar a classe de contexto chamada ApplicationDBContext:

public class AppDbContext : DbContext
    {
        public DbSet<Autor> Autores { get; set; }
        public DbSet<Livro> Livros { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                 .UseSqlServer("Data Source = MACORATTI; " +
                      "Initial Catalog=DemoDB;Integrated Security=True");
           optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole((category, level) =>
                level == LogLevel.Information &&
                   category == DbLoggerCategory.Database.Command.Name, true));
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //------entidade Autor--------------------
            modelBuilder.Entity<Autor>().HasKey(a => a.AutorId);
            modelBuilder.Entity<Autor>()
               .Property(p => p.Nome)
               .HasMaxLength(100)
               .IsRequired();
            modelBuilder.Entity<Autor>()
                .Property(p => p.Email)
                .HasMaxLength(200)
                .IsRequired();
            //------entidade Livro--------------------
            modelBuilder.Entity<Livro>().HasKey(a => a.LivroId);
            modelBuilder.Entity<Livro>()
                .Property(p => p.Titulo)
                .HasMaxLength(200)
                .IsRequired();
            //um-para-muitos :  Livros - Autor
            modelBuilder.Entity<Livro>()
              .HasOne<Autor>(s => s.Autor)
                .WithMany(g => g.Livros)
                   .HasForeignKey(s => s.AutorId);
        }
    }

Esta classe herda de DbContext e define o provedor do banco de dados SQL Server e a string de conexão com o banco de dados.

Define o mapeamento da entidade Autor para a tabela Autores e Livro para Livros e define o relacionamento um-para-muitos entre Autor e Livro usando a Fluent API.

Se o banco de dados e a tabela não existirem, podemos criar usando o Migrations.

Criando o banco de dados e a tabela com Migrations

Para criar o banco de dados e a tabela, abra o Package Manager Console e digite o comando: Add-Migration MigracaoInicial ou dotnet ef migrations add MigracaoInicial na linha de comando:

Para aplicar a migração e efetivamente criar o banco de dados e a tabela, digite o comando Update-Database no Package Manager Console ou dotnet ef database update na linha de comando:

Abrindo o SQL Server Management Studio verificamos que o banco de dados CursoEFCoreModulo11DB e as tabelas Autores e Livros foram criados com sucesso:

Vamos agora definir o código no arquivo Program.cs e criar uma instância do nosso contexto para acessar os autores e seus livros:

using EFCore_LazyLoading.Models;
using System;
namespace EFCore_LazyLoading
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var contexto = new AppDbContext())
            {
                var resultado = contexto.Autores;
                                       .Include(l=> l.Livros); 
                foreach (var item in resultado)
                {
                    Console.WriteLine($"{item.Nome}");
                    Console.WriteLine($"{item.Email}");
                    foreach (var l in item.Livros)
                    {
                        Console.WriteLine("\t\t" + l.Titulo);
                    }
                }
            }
            Console.Readkey();
        }
    }
}

Neste código estamos acessando os autores e exibindo o nome de cada autor, e a seguir, usando a propriedade de navegação Livros, exibindo o título dos livros para cada autor.

 var resultado = contexto.Autores;
                       .Include(l=> l.Livros);

Na consulta acima estamos usando o método Include e usando o recurso do Eager Loading para carregar os livros dos autores para a propriedade de navegação de coleção Livros.

Executando o projeto veremos o resultado no Console e também as consultas SQL geradas pelo EF Core para realizar a consulta:

E por hoje é isso.