EF Core - Populando dados iniciais (Data Seed) - IV


Hoje vamos continuar abordando o recurso disponível a partir da versão 2.1 do EF Core que facilita a alimentação das tabelas criadas com dados iniciais.

Vamos continuar a terceira parte do artigo mostrando uma forma melhor de aplicar a configuração e popular as tabelas com dados iniciais.

Nos artigos anteriores vimos que podemos colocar o código para configurar e popular as tabelas com dados iniciais no método OnModelCreating.

Ocorre que para um projeto maior contendo mais classes com mais dados o método ficaria cada vez maior e mais difícil de entender e de manter.

Pensando nisso o EF Core oferece uma forma melhor de criar uma configuração coma a Fluent API usando a interface IEntityTypeConfiguration<T> onde podemos dividir a configuração de cada entidade em sua própria classe de configuração separada. Assim temos um código mais compacto e fácil de manter.

Então, vamos ver como fazer isso usando o mesmo projeto dos artigos anteriores.

Nota: Veja como criar o projeto de exemplo usado neste artigo aqui.

Vamos definir uma nova entidade em nosso domínio chamada Aluno definindo a classe Aluno na pasta Models:

    public class Aluno
    {
        public int AlunoId { get; set; }
        public string Nome { get; set; }
        public int? Idade { get; set; }
    }

A seguir inclua na classe de contexto AppDbContext o mapeamento usando DBSet:

...    
   public DbSet<Aluno> Alunos { get; set; }
...

Pronto, agora vamos aplicar a configuração  vamos popular a tabela Alunos com dados iniciais.

No projeto e crie a pasta Configuration, e, a seguir crie a classe AlunoConfiguration que herda de IEntityTypeConfiguration<T> onde T é a nossa classe Aluno :

using ConsoleEFCore1.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
namespace ConsoleEFCore1.Configuration
{
    public class AlunoConfiguration : IEntityTypeConfiguration<Aluno>
    {
        public void Configure(EntityTypeBuilder<Aluno> builder)
        {
            throw new NotImplementedException();
        }
    }
}

A seguir vamos implementar no método Configure o código para popular a tabela Alunos usando HasData:

using ConsoleEFCore1.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ConsoleEFCore1.Configuration
{
    public class AlunoConfiguration : IEntityTypeConfiguration<Aluno>
    {
        public void Configure(EntityTypeBuilder<Aluno> builder)
        {
            builder.ToTable("Aluno");
            builder.Property(s => s.Idade)
                .IsRequired(false);
            builder.HasData
            (
                new Aluno
                {
                    AlunoId = 1,
                    Nome = "Maria",
                    Idade = 30
                },
                new Aluno
                {
                    AlunoId = 2,
                    Nome = "José",
                    Idade = 25
                },
                new Aluno
                {
                    AlunoId = 3,
                    Nome = "Mike Miles",
                    Idade = 28
                }
            );
        }
    }
}

Observe que como idade é um Nullable(int? idade) configuramos a propriedade Idade como não requerida.

Agora temos tudo definido e pronto para ser usado no arquivo AlunoConfiguration, e, agora tudo que precisamos fazer é modificar o método OnModelCreating da classe AppDbContext incluindo o código a seguir:

...
 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
     modelBuilder.ApplyConfiguration(new AlunoConfiguration());
 }
...

Usamos o método ApplyConfiguration() passando a instância da classe AlunoConfiguration().

Podemos agora criar e aplicar uma nova migração:

add-migration PopulaAlunos
update-database

Podemos conferir os dados incluídos usando esta abordagem usando o código abaixo:

     static void Main(string[] args)
        {
            using (var _context = new AppDbContext())
            {
                var alunos = _context.Alunos.ToList();
                foreach(var aluno in alunos)
                {
                    Console.WriteLine($"{aluno.Nome} {aluno.Idade}");
                }
            }
            Console.ReadLine();
        }

 

Estamos inicializando a tabela com dados e a seguir exibindo o seu conteúdo.  O resultado obtido será:

Podemos aplicar essa abordagem para cada entidade do nosso modelo e assim teremos classes de configuração separadas e assim um código mais organizado.

Pegue o projeto aqui: ConsoleEFCore1_SeedData4.zip (sem as referências)

Tu, pois, meu filho, fortifica-te na graça que há em Cristo Jesus.
2 Timóteo 2:1

Referências:


José Carlos Macoratti