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.