Partilhar via


Migrações automáticas do Code First

As Migrações Automáticas permitem que você use as Migrações do Code First sem ter um arquivo de código em seu projeto para cada alteração que você fizer. Nem todas as alterações podem ser aplicadas automaticamente. Por exemplo, as renomeações de coluna exigem o uso de uma migração baseada em código.

Observação

Este artigo pressupõe que você saiba usar as Migrações do Code First em cenários básicos. Caso contrário, será necessário ler Migrações do Code First antes de continuar.

Recomendação para ambientes de equipe

Você pode intercalar migrações automáticas e baseadas em código, mas isso não é recomendado em cenários de desenvolvimento de equipe. Se você fizer parte de uma equipe de desenvolvedores que usa o controle do código-fonte, deverá usar migrações puramente automáticas ou migrações puramente baseadas em código. Considerando as limitações das migrações automáticas, recomendamos o uso de migrações baseadas em código em ambientes de equipe.

Criando um modelo inicial e um banco de dados

Antes de começar a usar as migrações, é necessário um projeto e um modelo do Code First com os quais trabalhar. Para este passo a passo, usaremos o Blog canônico e o modelo Post.

  • Crie um novo aplicativo de console MigrationsAutomaticDemo
  • Adicione a versão mais recente do pacote NuGet EntityFramework ao projeto
    • Ferramentas –> Gerenciador de Pacotes de Biblioteca –> Console do Gerenciador de Pacotes
    • Execute o comando Install-Package EntityFramework
  • Adicione um arquivo Model.cs com o código mostrado abaixo. Esse código define uma única classe Blog que compõe o nosso modelo de domínio e uma classe BlogContext que é o nosso contexto do EF Code First
    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;

    namespace MigrationsAutomaticDemo
    {
        public class BlogContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
        }

        public class Blog
        {
            public int BlogId { get; set; }
            public string Name { get; set; }
        }
    }
  • Agora que temos um modelo, é hora de usá-lo para executar o acesso a dados. Atualize o arquivo Program.cs com o código mostrado abaixo.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MigrationsAutomaticDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db = new BlogContext())
                {
                    db.Blogs.Add(new Blog { Name = "Another Blog " });
                    db.SaveChanges();

                    foreach (var blog in db.Blogs)
                    {
                        Console.WriteLine(blog.Name);
                    }
                }

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
  • Execute o aplicativo e você verá que um banco de dados MigrationsCodeDemo.BlogContext é criado.

    Banco de dados LocalDB

Habilitando as migrações

É hora de fazer mais algumas alterações em nosso modelo.

  • Vamos introduzir uma propriedade URL para a classe Blog.
    public string Url { get; set; }

Se você fosse executar o aplicativo novamente, obteria um InvalidOperationException informando O modelo dando suporte ao contexto 'BlogContext' foi alterado desde que o banco de dados foi criado. Considere usar as Migrações do Code First para atualizar o banco de dados ( http://go.microsoft.com/fwlink/?LinkId=238269).

Como a exceção sugere, é hora de começar a usar as Migrações do Code First. Como queremos usar migrações automáticas, vamos especificar a opção –EnableAutomaticMigrations.

  • Execute o comando Enable-Migrations – EnableAutomaticMigrations no Console do Gerenciador de Pacotes. Esse comando adicionou uma pasta Migrações ao nosso projeto. Essa nova pasta contém um arquivo:

  • A classe Configuration. Essa classe permite que você configure o comportamento das Migrações para seu contexto. Para este passo a passo, usaremos apenas a configuração padrão. Como há apenas um único contexto do Code First no projeto, Enable-Migrations preencheu automaticamente o tipo de contexto ao qual essa configuração se aplica.

 

Sua primeira migração automática

As Migrações do Code First têm dois comandos principais com os quais você se familiarizará.

  • Add-Migration realizará o scaffolding da próxima migração com base nas alterações feitas no modelo desde a criação da última migração
  • Update-Database aplicará quaisquer migrações pendentes ao banco de dados

Vamos evitar o uso de Add-Migration (a menos que realmente precisemos) e nos concentrar em permitir que as Migrações do Code First calculem e apliquem automaticamente as alterações. Vamos usar Update-Database para obter migrações do Code First para enviar as alterações em nosso modelo por push (a nova propriedade Blog.Url) para o banco de dados.

  • Execute o comando Update-Database no Console do Gerenciador de Pacotes

O banco de dados MigrationsDemo.BlogContext foi atualizado para incluir a coluna Url na tabela Blogs.

 

Sua segunda migração automática

Vamos fazer outra alteração e permitir que as Migrações do Code First enviem automaticamente as alterações para o banco de dados para nós.

  • Vamos adicionar também uma nova classe Post
    public class Post
    {
        public int PostId { get; set; }
        [MaxLength(200)]
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
  • Também adicionaremos uma coleção Posts à classe Blog para formar a outra extremidade do relacionamento entre Blog e Post
    public virtual List<Post> Posts { get; set; }

Agora, use Update-Database para atualizar o banco de dados. Dessa vez, vamos especificar o sinalizador –Verbose para que você possa ver o SQL que as Migrações do Code First estão executando.

  • Execute o comando Update-Database –Verbose no Console do Gerenciador de Pacotes.

Como adicionar uma migração baseada em código

Agora vamos examinar um cenário para o qual talvez queiramos usar uma migração baseada em código.

  • Vamos adicionar uma propriedade Rating à classe Blog
    public int Rating { get; set; }

Poderíamos apenas executar Update-Database para enviar essas alterações por push para o banco de dados. No entanto, estamos adicionando uma coluna Blogs.Ratingnão anulável. Se houver dados existentes na tabela, ela receberá o padrão CLR do tipo de dados para nova coluna (Rating é inteiro, de modo que seria 0). Mas queremos especificar um valor padrão de 3 de forma que as linhas existentes na tabela Blogs comecem com uma classificação decente. Vamos usar o comando Adicionar Migração para gravar essa alteração em uma migração baseada em código para que possamos editá-la. O comando Add-Migration nos permite atribuir um nome a essas migrações. Vamos chamar a nossa de AddBlogUrl.

  • Execute o comando Add-Migration AddBlogUrl no Console do Gerenciador de Pacotes.
  • Agora, na pasta Migrações temos uma nova migração AddBlogUrl. O nome do arquivo de migração é previamente corrigido com um carimbo de data/hora para ajudar com a ordenação. Vamos editar o código gerado para especificar um valor padrão de 3 para Blog.Rating (Linha 10 no código abaixo)

A migração também tem um arquivo code-behind que captura alguns metadados. Esses metadados permitirão que as Migrações do Code First repliquem as migrações automáticas que executamos antes dessa migração baseada em código. Isso é importante se outro desenvolvedor quiser executar nossas migrações ou quando for a hora de implantar nosso aplicativo.

    namespace MigrationsAutomaticDemo.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;

        public partial class AddBlogRating : DbMigration
        {
            public override void Up()
            {
                AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
            }

            public override void Down()
            {
                DropColumn("Blogs", "Rating");
            }
        }
    }

Nossa migração editada parece boa, portanto, vamos usar Update-Database para atualizar o banco de dados.

  • Execute o comando Update-Database no Console do Gerenciador de Pacotes

Voltar para migrações automáticas

Agora estamos livres para voltar para migrações automáticas para nossas alterações mais simples. As Migrações do Code First cuidarão da execução das migrações automáticas e baseadas em código na ordem correta com base nos metadados que ele está armazenando no arquivo code-behind para cada migração baseada em código.

  • Vamos adicionar uma propriedade Post.Abstract ao nosso modelo.
    public string Abstract { get; set; }

Agora podemos usar Update-Database para obter migrações do Code First para enviar essa alteração por push para o banco de dados usando uma migração automática.

  • Execute o comando Update-Database no Console do Gerenciador de Pacotes

Resumo

Neste passo a passo, você viu como usar migrações automáticas para enviar alterações de modelo por push para o banco de dados. Você também viu como estruturar e executar migrações baseadas em código entre migrações automáticas quando precisar de mais controle.