Partilhar via


Personalização da tabela de histórico de migrações

Observação

Apenas a partir do EF6 - As funcionalidades, APIs, etc. discutidas nesta página foram introduzidas no Entity Framework 6. Se estiver a usar uma versão anterior, parte ou toda a informação não se aplica.

Observação

Este artigo assume que você sabe usar Migrações Code First em cenários básicos. Se não o fizeres, então terás de ler Code First Migrations antes de continuar.

O que é a Tabela de Histórico de Migrações?

A tabela de histórico de migrações é uma tabela utilizada pela Code First Migrations para armazenar detalhes sobre migrações aplicados à base de dados. Por defeito, o nome da tabela na base de dados é __MigrationHistory e é criado ao aplicar a primeira migração à base de dados. No Entity Framework 5, esta tabela era uma tabela de sistema se a aplicação utilizasse a base de dados Microsoft SQL Server. No entanto, isto mudou no Entity Framework 6 e a tabela de histórico de migrações já não está marcada como tabela de 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 Code First, e alterá-la manualmente pode comprometer as migrações. No entanto, por vezes a configuração padrão não é adequada e a tabela precisa de ser personalizada, por exemplo:

  • Precisa de alterar nomes e/ou facetas das colunas para permitir o funcionamento de um fornecedor de migrações de terceiros
  • Queres mudar o nome da tabela
  • Precisas de usar um esquema não padrão para a tabela de __MigrationHistory
  • Precisa de armazenar dados adicionais para uma dada versão do contexto e, por isso, precisa de adicionar uma coluna adicional à tabela

Palavras de precaução

Alterar a tabela de histórico de migração é poderoso, mas tens de ter cuidado para não exagerar. O tempo de execução do EF atualmente não verifica se a tabela de histórico de migrações personalizada é compatível com o tempo de execução. Se não for, a sua aplicação pode avariar em tempo de execução ou comportar-se de forma imprevisível. Isto é ainda mais importante se usares múltiplos contextos por base de dados, caso em que vários contextos podem usar a mesma tabela de histórico de migrações para armazenar informação sobre migrações.

Como personalizar a Tabela de Histórico de Migrações?

Antes de começares, precisas de saber que só podes personalizar a tabela de histórico de migrações antes de aplicares a primeira migração. Agora, ao código.

Primeiro, terá de criar uma classe derivada da classe System.Data.Entity.Migrations.History.HistoryContext. A classe HistoryContext deriva da classe DbContext, por isso configurar a tabela de histórico de migrações é muito semelhante a configurar modelos EF com API fluente. Só precisas de sobrescrever o método OnModelCreating e usar a API fluent para configurar a tabela.

Observação

Normalmente, quando configuras modelos EF, não precisas de chamar base.OnModelCreating() do método OnModelCreating sobreposto, uma vez que o DbContext.OnModelCreating() tem um corpo vazio. Isto não acontece ao configurar a tabela de histórico de migrações. Neste caso, a primeira coisa a fazer ao sobrescrever o método OnModelCreating() é realmente chamar base.OnModelCreating(). Isto vai configurar a tabela de histórico de migrações da forma padrão, que depois ajusta no método de sobreposição.

Imagina que queres renomear a tabela de histórico de migrações e colocá-la num esquema personalizado chamado "admin". Além disso, o seu DBA gostaria que renomeasse a coluna MigrationId para Migration_ID.  Pode conseguir isto criando a seguinte classe derivada do 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");
            }
        }
    }

Quando o seu HistoryContext personalizado estiver pronto, precisa de fazer com que o EF o reconheça, registando-o através 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 isto. Agora podes ir à Package Manager Console, Enable-Migrations, Add-Migration e, finalmente, Update-Database. Isto deverá resultar na adição à base de dados de uma tabela de histórico de migrações configurada de acordo com os detalhes que especificou na sua classe derivada do HistoryContext.

Tabela de História das Migrações