EF Core - Apresentando e usando o Migrations - I
Hoje vamos iniciar uma série de artigos que apresenta o Migrations e seus principais recursos. |
Atualmente (junho/2020) a versão estável do EF Core é a versão 3.1.4, mas já temos as versões preview do EF core 5.0.0 conforme você pode conferir aqui.
Para acompanhar as mudanças feitas no modelo de dados e manter a sincronia do modelo com o banco de dados o EF Core oferece o recurso Migrations ou Migrações que permite atualizar de forma incremental o esquema do banco de dados e assim mantê-lo sincronizado com o modelo de dados do seu projeto preservando os dados existentes.
A seguir temos as principais tarefas do Migrations usando ferramentas de linha de comando e APIs:
Crie uma migração. Gere código que pode atualizar o banco de dados para sincronizá-lo com um conjunto de alterações de modelo.
Para poder usar o recurso Migrations a primeira coisa a fazer é instalar as ferramentas do Entity Framework Core que ajudam nas tarefas de desenvolvimento em tempo de projeto e são usadas para gerar migrações e fazer a engenharia reversa do esquema do banco de dados. Podemos usar essas ferramentas de duas maneiras:
O EF Core utiliza um conjunto de convenções para criar um modelo com base nas suas entidades, dessa forma para aplicar o recurso Migrations no seu projeto você precisa definir :
Nota: Você pode usar o método OnModelCreating na classe de contexto para configurar o seu modelo de entidades e também pode aplicar atributos às suas entidades usando Data Annotations
Criando e aplicando o Migrations
Vamos agora criar e aplicar o Migrations usando como exemplo um projeto ASP .NET Core do tipo API que já esta criado e pronto para ser usado.
|
Nota: Veja como criar o projeto de exemplo usado neste artigo aqui.
O processo de criar e aplicar o Migrations envolve duas etapas:
Como já dissemos,
nosso esquema de banco de dados deve estar alinhado com o modelo e todas as alterações em um modelo de precisam ser migradas
para o próprio banco de dados.
Durante o desenvolvimento geralmente é necessários alterar o modelo de entidades
fazendo alterações nas propriedades do modelo ou incluindo e removendo
propriedades DbSet<> da classe de contexto, etc.
No nosso exemplo temos um projeto configurado e pronto para ser usado e vamos iniciar criando uma migração e a seguir aplicando a migração para que sejam gerados o banco de dados AlunosDBWeb e a tabela Alunos no SQL Server.
a - Criando a migração
Para criar a migração no VS 2019 Community podemos abrir a janela do Package Manager Console (PMC) e digitar o comando:
Add-Migration NomeDaMigração [options]
Este comando precisa do pacote Microsoft.EntityFrameworkCore.Tools instalado para funcionar.
Usando o VS Code e a ferramenta de linha de comando CLI o comando é:
dotnet ef migrations add NomeDaMigração [options]
Para este comando funcionar temos instalar a ferramenta de linha de comando do EF Core globalmente usando o comando:
dotnet tool install --global dotnet-ef
Vamos abrir o projeto ASP .NET Core e na janela do PMC digitar o comando: add-migration MigracaoInicial
O projeto será compilado e o arquivo de script gerado conforme abaixo:
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace AspNet_EFCoreApi.Migrations
{
public partial class MigracaoInicial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Alunos",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Nome = table.Column<string>(nullable: true),
Idade = table.Column<int>(nullable: true),
Ativo = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Alunos", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Alunos");
}
}
}
|
Temos aqui a classe MigracaoInicial que herda de Migration e define dois métodos : Up e Down.
No método Up() temos os comandos para criar a tabela Alunos onde as colunas da tabela possuem os mesmos nomes das propriedades definidos na classe Aluno. No método Down temos o comando para remover a tabela criada caso desejamos remover a migração.
Esses dois métodos são usados na classe que herda de Migration para definir as alterações que serão aplicadas ao banco de dados, sendo que no método Up() aplica o script e o método Down() reverte a aplicação feita.
Assim, se você cometeu algum erro e deseja remover a migração basta digitar: Remove-Migration o método Down será executado e a migração será revertida.
Note que é criada uma pasta Migrations no projeto contendo os arquivos de migração:
Aqui temos os arquivos:
O registro de data e hora no nome do arquivo ajuda a mantê-los em ordem cronológica, para que você possa ver a progressão das alterações.
b - Aplicando a migração
Depois de criar nossa migração com sucesso, precisamos aplicá-la para que as alterações entrem em vigor no banco de dados.
Existem várias maneiras de aplicar migrações (usando scripts SQL, usando o método Database.Migrate ou usando métodos de linha de comando) e, como fizemos na criação, vamos usar a abordagem de métodos de linha de comando.
Usando o VS 2019 na janela do PMC podemos emitir o comando: update-database [options]
Usando o VS Code e a ferramenta NET CLI o comando usado é : dotnet ef database update [options]
Para o nosso exemplo vamos digitar o comando : update-database
Ao final do processamento teremos o banco de dados AlunosDBWeb e a tabela Alunos criada no SQL Server conforme as convenções usadas pelo EF Core e segundo as configurações definidas em nosso projeto ASP .NET Core.
Abrindo o SQL Server Management Studio podemos confirmar a criação do banco de dados AlunosDBWeb e a tabela Alunos contendo as colunas : Id, Nome, Idade e Ativo.
Observe a tabela _EFMigrationsHistory que foi criada no banco de dados.
O EF Core usa esta
tabela para rastrear todas as migrações aplicadas. Portanto, isso significa que,
se criarmos outra migração em nosso código e aplicá-lo, o EF Core aplicará
apenas a migração recém-criada.
Mas como o EF Core sabe qual migração precisa ser aplicada ?
Bem, ele armazena um ID exclusivo no _EFMigrationsHistory,
que é um nome exclusivo do arquivo de migração criado com a migração e nunca
executa arquivos com o mesmo nome novamente.
Podemos confirmar isso abrindo essa tabela e comparar o valor de MigrationId com o nome do arquivo de migração gerado.
Cada migração é aplicada em uma transação SQL, o que significa que toda a migração é bem-sucedida ou falha. Se tivermos várias migrações para aplicar, elas serão aplicadas na ordem exata em que são criadas.
Agora observe que a coluna Nome foi gerada como um nvarchar(max) a partir da propriedade Nome do tipo string na entidade Aluno.
using System;
public class Aluno
{
public Guid Id { get; set; }
public string Nome { get; set; }
public int? Idade { get; set; }
public bool Ativo { get; set; }
}
|
Podemos corrigir isso definindo na propriedade Nome da enitdade Aluno dois atributos atributo que serão aplicados via Data Annotations que usa o namespace System.ComponentModel.DataAnnotations :
using System;
using System.ComponentModel.DataAnnotations;
namespace AspNet_EFCoreApi.Models
{
public class Aluno
{
public Guid Id { get; set; }
[Required(ErrorMessage ="Informe o nome do aluno")]
[MaxLength(80, ErrorMessage = "O nome deve ter no máximo 80 caracteres")]
public string Nome { get; set; }
public int? Idade { get; set; }
public bool Ativo { get; set; }
}
}
|
Nota: Poderíamos ter feito o mesmo ajuste no método OnModelCreating conforme mostrado a seguir:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Aluno>()
.ToTable("Alunos");
modelBuilder.Entity<Aluno>()
.Property(s => s.Id)
.HasColumnName("AlunoId");
modelBuilder.Entity<Aluno>()
.Property(s => s.Nome)
.IsRequired()
.HasMaxLength(80);
modelBuilder.Entity<Aluno>()
.Property(s => s.Idade)
.IsRequired(false);
}
|
Assim agora podemos aplicar outra migração emitindo o comando: add-migration AjusteColunaNome
A seguir vamos aplicar a migração digitando: update-database
E se verificarmos o banco de dados veremos a nova migração emitida e agora a coluna nome possui o tamanho de 80 conforme esperado:
Na próxima parte do artigo veremos como adicionar um código customizado ao arquivo de migração.
Pegue o projeto aqui : AlunosWeb.zip (sem as referências)
"Porque pela graça sois salvos, por meio da fé; e isto não
vem de vós, é dom de Deus.
Não vem das obras, para que ninguém se glorie;"
Efésios 2:8,9
Referências:
EF Core 3.x - Atualizações recentes -
Curso Entity Framework Core 2.0 - Vídeo Aulas
EF Core - Usando a abordagem DataBase First ..
EF Core - Conceitos Básicos - Macoratti.net
Usando o EF Core com Windows Forms - (Crud ..