Entity Framework - Usando o recurso Code First - Migrations


Neste artigo eu vou apresentar o novo recurso do Entity Framework chamado Migrations.

O que vem a ser o recurso Migrations ?

O Code First funciona muito bem e é muito fácil de usar. Mas ele não tem uma característica importante, o tratamento das alterações do esquema de banco de dados (adicionar/remover/modificar colunas, tipos de dados, restrições, etc.) relacionadas com as alterações feitas no modelo de entidades.

Usando o Code First quando você altera o modelo de entidades gerado você tem que recriar o seu banco de dados novamente acarretando assim perda dos dados ou tem que gerar scripts SQL para manualmente refletir as alterações no banco de dados se não quiser perder os dados.

O Migrations veio para suprir a falta deste recurso no Code First.

Usando o recurso MIgrations do Entity Framework podemos realizar alterações em nosso modelo de entidades e ter a atualização automática do banco de dados refletindo essas mudanças.

Através do Code First podemos gerar de forma automática o nosso modelo de dados a partir do modelo de entidades e com o Migrations podemos gerar atualizações no banco de dados refletindo as alterações porventura feitas  no modelo de entidades.

Dessa forma o Migrations pode ser usado com o Code First para automatizar de vez o processo de geração e atualização do modelo de dados com base no modelo de entidades onde o Migrations vai manter o modelo de dados gerado via Code First sempre atualizado com as classes do modelo de entidades.

Podemos usar o Migrations de forma totalmente automática onde todo o processo de atualização do banco de dados é feita de forma transparente pelo Migrations.

Podemos também definir manualmente pontos de migração quer aplicando as últimas modificações ou regredindo para uma modificação anterior através da geração de scripts e sua posterior execução.

Neste artigo  eu estou usando o Visual Studio 2010 Ultimate mas você já pode usar o Visual Studio 2012 encontrado neste link: http://www.microsoft.com/visualstudio/11/en-us/downloads

Usando o Entity Framework Migrations

Abra o Visual Studio 2010 e clique no link New Project ou no menu File clique em New Project e escolha o template Visual Basic -> Windows -> Console Application;

Informe o nome EF_Migrations e clique no botão OK;

Vamos agora instalar o Entity Framework em nosso projeto usando o gerenciador de pacotes Nuget do Visual Studio;

Com o Nuget podemos instalar bibliotecas e pacotes no Visual Studio sendo que na instalação o Nuget adiciona as bibliotecas, as referências e faz todas as alterações necessárias nos arquivos de configuração então sempre é bom usar os recursos do Nuget.

Salve a solução antes de prosseguir.

No menu Tools clique em Library Package Manager e a seguir em Package Manager Console;

Será aberto o Console do Package Manager e para instalar o Entity Framework 5.0 digite o comando : Install-Package EntityFramework e tecle ENTER;

Ao final do processo você verá no console as mensagens indicando o êxito da operação:

Vamos agora definir o nosso modelo de entidades criando uma classe chamada Produto em nossa solução;

No menu Project clique  em Add Class e informe o nome Produto.vb e clique em Add;

A seguir digite o código abaixo que define 3 propriedades na classe Produto:

Public Class Produto	

  Public Property produtoid As Integer
  Public
Property produtonome As String

End Class
 
    Private m_Id As Integer
    Public Property Id() As Integer
        Get
            Return m_Id
        End Get
        Set(ByVal value As Integer)
            m_Id = value
        End Set
    End Property

 

Obs: A direita eu mostro um exemplo de como era sintaxe antiga na definição de uma propriedade para a propriedade Id. A sintaxe das propriedades automáticas simplificam o código.

Agora vamos definir uma classe para nosso contexto chamada Contexto que herda de DbContext e que será responsável pela criação do banco de dados;

Imports System.Data.Entity
Public Class Contexto
    Inherits DbContext
    Public Property Produtos As DbSet(Of Produto)

End Class
O DbContext é um invólucro para ObjectContext e além disso esta classe contém:

- Um conjunto de APIs que são mais fáceis de usar do que a exposta pelo ObjectContext;

- As APIs que permitem utilizar o recurso do Code-First e as convenções;

 

Agora que temos o nosso  modelo de entidades pronto vamos definir o código no Modulo da solução para vermos o Code-First em ação:

Digite o código abaixo no módulo Module1.vb:

Module Module1
    Sub Main()

     Try

      Using _contexto As New Contexto()

           Dim produto1 = New Produto() With {.produtonome = "Teclado"}

           _contexto.Produtos.Add(produto1)


          Dim
produto2 = New Produto() With {.produtonome = "Mouse Ótico"}

          _contexto.Produtos.Add(produto2)
 

         _contexto.SaveChanges()
 

         Console.WriteLine(" Banco de dados e tabelas cridas com sucesso")

       End Using

   Catch ex As Exception

      Console.WriteLine(" Erro : " + ex.Message)

    End Try


  
Console.ReadKey()

End Module

Agora vamos rodar a solução pressionando F5.

A execução norma do programa deverá exibir uma mensagem no Console conforme a figura abaixo:

Concluímos então que o banco de dados e a tabela foram criados no SQL server e que a tabela deverá conter dois registros.

Vamos verificar !!!!

Como eu sei o nome do banco de dados que foi criado  ??

Eu poderia ter definido no arquivo de configuração App.Config a string de conexão e indicar nome banco de dados, mas como não fiz isso o padrão que o Entity Framework usa é o seguinte:

A API DbContext por convenção cria o banco de dados para você em localhost\SQLEXPRESS e o nome do banco de dados é derivado a partir do nome do projeto e do contexto, no nosso caso : EF_MIgrations.Contexto

Abra a janela Server Explorer no Visual Studio;

Clique com o botão direito do mouse sobre Data Connections e no menu clique em Add Connection;

Na janela Add Connection informe o nome do servidor, no nosso caso : .\sqlexpress e clique na combo para selecionar o banco de dados;

Procurando na relação de bancos existentes verificamos o nosso banco de dados que foi criado via code First: EF_Migrations.Contexto;

Clique no botão OK para exibir o banco de dados na janela do Server Explorer;

Expandindo itens podemos verificar a tabela Produtoes contendo os campos produtoid e produtonome e os registros que foram incluídos na tabela:

Por que o nome Produtoes ???

A tabela foi definida com o nome Produtoes porque o Entity Framework pluraliza o nome da tabela usando a regra do idioma inglês , ou seja, acrescenta es ao final do nome.

Bem , até agora tudo certo.  Usamos o Code-First para criar o banco de dados e as tabelas mas e o MIgrations ??? Onde ele entra nessa história ???

Vamos experimentar alterar a classe Produto incluindo a definição de mais uma propriedade. Abra o arquivo Produto.vb e inclua a propriedade produtopreco no código conforme abaixo:

Public Class Produto
    Public Property produtoid As Integer
    Public Property produtonome As String
    Public Property produtopreco As Double
End Class

Dessa forma nosso modelo de entidades foi alterado. Vamos executar o projeto novamente e ver o resultado.

Vai ocorrer um erro que pode ser visto no Console conforme a figura a seguir:

O erro indica que o modelo foi alterado desde que o banco de dados foi criado e sugere a utilização do Migrations para atualizar o banco de dados.

É isso que vamos fazer: habilitar o MIgrations.

Nossa próxima tarefa será utilizar o Code First Migrations habilitando-o e adicionando-o ao projeto usando o Package Manager Console.

No menu Tools clique em Library Package Manager e a seguir em Package Manager Console;

A janela do console será aberta conforme a figura abaixo:

Comece a digitar Ena e pressione a tecla Tab;

Será aberto uma relação de comandos. Selecione Enable-Migrations e pressione ENTER;

Após alguns momentos teremos o término da execução do comando e veremos a mensagem no Console;

Veremos também que foi criada uma pasta no projeto chamada Migrations e que a pasta contém dois arquivos:

O primeiro arquivo tem o nome composto por um timestamp acrescido de  _InitialCreate. Como o nome indica a classe  InitialCreate é usada iniciar a criação de tabelas e sua estrutura;

No método Up() vemos o código que cria a tabela Produtoes e os campos produtoid e produtonome; (Observe que a classe herda de DbMigration que é a classe base)

Note que temos o método Down que permite excluir a tabela Produtoes;

O arquivo Configuration.vb permite definir qual o comportamento do Migrations para o nosso contexto. Vemos no construtor da classe a propriedade AutomaticMigrationsEnabled definida como False indicando que a migração automática não será usada no processo de migração do banco de dados.

Assim já temos o Migrations habilitado.

Agora temos que continuar com o processo e para isso o Migrations possui dois comandos:

  1. Add-MIgration - que gera o código para atualizar o banco de dados de acordo com as alterações feitas no modelo de entidades;
  2. Update-Database - que vai aplicar as alterações pendentes no banco de dado;

Então vamos digitar o comando Add-Migration seguido do nome IncluirPrecoProduto que indica a alteração feita na classe Produto, e pressionar ENTER;

O resultado pode ser visto na figura abaixo:

O comando criou o arquivo 201208261702089_IncluirPrecoProduto.vb na pasta Migrations onde vemos a classe IncluirPrecoProduto que herda de DbMigration e dois métodos:

Agora para aplicar a alteração feita no modelo de entidades no banco de dados temos que executar o comando Update-DataBase no console e teclar ENTER:

Abaixo vemos o resultado da execução no Console:

Se abrirmos a janela Server Explorer e atualizarmos a exibição veremos a nova coluna produtopreco já incluída na tabela Produtoes:

O code first Migrations vai comparar as migrações em nossa pasta Migrations com as que foram aplicadas ao banco de dados e vai reconhecer que a migração IncluirPrecoProduto precisa ser aplicada executando-a.

Dessa forma o banco de dados esta atualizado refletindo agora a alteração feita na classe Produto.

Assim podemos realizar qualquer alteração no modelo e fazer a atualização do modelo de dados usando o Code First Migrations conforme mostrei neste artigo.

Aguarde mais artigos sobre o Code First Migrations onde irei abordar outros recursos do Entity Framework e do Migrations.

Pegue o projeto completo aqui : EF_Migrations.zip

1Pedro 2:15 Porque assim é a vontade de Deus, que, fazendo o bem, façais emudecer a ignorância dos homens insensatos,
1Pedro 2:16
como livres, e não tendo a liberdade como capa da malícia, mas como servos de Deus.

Referências:


José Carlos Macoratti