Compartilhar via


Personalizar a tabela de histórico de migrações

Observação

EF6 em diante apenas: os recursos, as APIs etc. discutidos nessa página foram introduzidos no Entity Framework 6. Se você estiver usando uma versão anterior, algumas ou todas as informações não se aplicarão.

Observação

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

O que é a tabela de histórico de migrações?

A tabela de histórico de migrações é usada pelas Migrações do Code First para armazenar detalhes sobre migrações aplicadas ao banco de dados. Por padrão, o nome da tabela no banco de dados é __MigrationHistory e ele é criado ao aplicar a primeira migração ao banco de dados. No Entity Framework 5, essa tabela era uma tabela do sistema se o aplicativo usasse o banco de dados do Microsoft Sql Server. No entanto, isso foi alterado no Entity Framework 6 e a tabela de histórico de migrações não está mais marcada como uma tabela do sistema.

Por que personalizar a tabela de histórico de migrações?

A tabela de histórico de migrações deve ser usada exclusivamente pelas Migrações do Code First e alterá-la manualmente pode interromper as migrações. No entanto, às vezes, a configuração padrão não é adequada e a tabela precisa ser personalizada, por exemplo:

  • Você precisa alterar nomes e/ou facetas das colunas para habilitar um provedor de migrações terceirizado
  • Você quer alterar o nome da tabela
  • Você precisa usar um esquema não padrão para a tabela __MigrationHistory
  • Você precisa armazenar dados adicionais para uma determinada versão do contexto e, portanto, precisa acrescentar uma coluna adicional na tabela

Palavras de precaução

A alteração da tabela de histórico de migração é poderosa, mas você precisa ter cuidado para não exagerar. Atualmente, o runtime do EF não verifica se a tabela personalizada de histórico de migrações é compatível com o runtime. Se não for, seu aplicativo poderá interromper no runtime ou se comportar de maneiras imprevisíveis. Isso é ainda mais importante se você usar vários contextos por banco de dados, caso em que vários contextos podem usar a mesma tabela de histórico de migração para armazenar informações sobre migrações.

Como personalizar a tabela de histórico de migrações?

Antes de começar, você precisa saber que pode personalizar a tabela de histórico de migrações somente antes de aplicar a primeira migração. Agora, vamos ao código.

Primeiro, você precisará criar uma classe derivada da classe System.Data.Entity.Migrations.History.HistoryContext. A classe HistoryContext é derivada da classe DbContext e, portanto, configurar a tabela de histórico de migrações é muito semelhante à configuração de modelos do EF com API fluente. Você só precisa substituir o método OnModelCreating e usar a API fluente para configurar a tabela.

Observação

Normalmente, ao configurar modelos do EF, você não precisa chamar base.OnModelCreating() do método OnModelCreating substituído desde que DbContext.OnModelCreating() tenha corpo vazio. Esse não é o caso ao configurar a tabela de histórico de migrações. Nesse caso, a primeira coisa a fazer na sua substituição de OnModelCreating() é realmente chamar base.OnModelCreating(). Isso configurará a tabela de histórico de migrações da maneira padrão que você, então, ajustará no método de substituição.

Digamos que você queira renomear a tabela de histórico de migrações e colocá-la em um esquema personalizado chamado “administrador”. Além disso, o DBA gostaria que você renomeasse a coluna MigrationId para Migration_ID.  Você pode conseguir isso criando a seguinte classe derivada da classe HistoryContext:

    using System.Data.Common;
    using System.Data.Entity;
    using System.Data.Entity.Migrations.History;

    namespace CustomizableMigrationsHistoryTableSample
    {
        public class MyHistoryContext : HistoryContext
        {
            public MyHistoryContext(DbConnection dbConnection, string defaultSchema)
                : base(dbConnection, defaultSchema)
            {
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Entity<HistoryRow>().ToTable(tableName: "MigrationHistory", schemaName: "admin");
                modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID");
            }
        }
    }

Depois que a classe HistoryContext personalizada estiver pronta, você precisará fazer com que o EF saiba disso registrando-a por meio de configuração baseada em código:

    using System.Data.Entity;

    namespace CustomizableMigrationsHistoryTableSample
    {
        public class ModelConfiguration : DbConfiguration
        {
            public ModelConfiguration()
            {
                this.SetHistoryContext("System.Data.SqlClient",
                    (connection, defaultSchema) => new MyHistoryContext(connection, defaultSchema));
            }
        }
    }

É basicamente isso. Agora você pode ir para o Console do Gerenciador de Pacotes, Habilitar Migrações, Adicionar Migração e, por fim, Atualizar Banco de Dados. Isso deve resultar na adição ao banco de dados de uma tabela de histórico de migrações configurada de acordo com os detalhes especificados na sua classe derivada de HistoryContext.

Migrations History Table