Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
À medida que o modelo muda, as migrações são adicionadas e removidas como parte do desenvolvimento normal, e os arquivos de migração são verificados no controle do código-fonte do projeto. Para gerenciar migrações, você deve primeiro instalar as ferramentas de linha de comando EF Core.
Tip
Se o DbContext estiver em um assembly diferente do projeto de inicialização, você poderá especificar explicitamente os projetos de destino e inicialização nas ferramentas do Console do Gerenciador de Pacotes ou nas ferramentas da CLI do .NET.
Adicionar uma migração
Depois que o modelo for alterado, você poderá adicionar uma migração para essa alteração:
- da CLI do .NET
- Estúdio Visual
dotnet ef migrations add AddBlogCreatedTimestamp
O nome da migração pode ser usado como uma mensagem de confirmação em um sistema de controle de versão. Por exemplo, você pode escolher um nome como AddBlogCreatedTimestamp se a alteração for uma nova propriedade CreatedTimestamp em sua entidade Blog.
Três ficheiros são adicionados ao seu projeto no diretório Migrations:
-
XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.cs--O arquivo de migrações principal. Contém as operações necessárias para aplicar a migração (em
Up) e para revertê-la (emDown). - XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.Designer.cs--O arquivo de metadados de migrações. Contém informações usadas pela EF.
- MyContextModelSnapshot.cs--Um instantâneo do seu modelo atual. Usado para determinar o que mudou ao adicionar a próxima migração.
O carimbo de data/hora no nome do arquivo ajuda a mantê-los ordenados cronologicamente para que você possa ver a progressão das alterações.
Namespaces
Você é livre para mover arquivos de migração e alterar seu namespace manualmente. Novas migrações são criadas como paralelas à última migração. Como alternativa, você pode especificar o diretório no momento da geração da seguinte maneira:
- da CLI do .NET
- Estúdio Visual
dotnet ef migrations add InitialCreate --output-dir Your/Directory
Note
Você também pode alterar o namespace independentemente do diretório usando --namespace.
Crie e aplique uma migração num só passo
Note
Esta funcionalidade foi adicionada no EF Core 11.
O dotnet ef database update comando suporta a criação e aplicação de uma migração num único passo usando a --add opção. Isto utiliza o Roslyn para compilar a migração em tempo de execução, permitindo cenários como o .NET Aspire e aplicações containerizadas onde a aplicação não pode ser parada e reconstruída:
- da CLI do .NET
- Estúdio Visual
dotnet ef database update InitialCreate --add
As mesmas opções disponíveis para dotnet ef migrations add podem ser usadas:
dotnet ef database update AddProducts --add --output-dir Migrations/Products --namespace MyApp.Migrations
Este comando estrutura uma nova migração com o nome especificado, compila-a usando o Roslyn e aplica-a imediatamente à base de dados. Os ficheiros de migração continuam guardados no disco para controlo de versões e recompilação futura.
Se não forem detetadas alterações pendentes no modelo, o comando aplica quaisquer migrações pendentes existentes sem criar uma nova.
Personalizar o código de migração
Embora o EF Core geralmente crie migrações precisas, você deve sempre revisar o código e verificar se ele corresponde à alteração desejada; Em alguns casos, é mesmo necessário fazê-lo.
Renomeações de colunas
Um exemplo notável em que a personalização de migrações é necessária é ao renomear uma propriedade. Por exemplo, se você renomear uma propriedade de Name para FullName, o EF Core gerará a seguinte migração:
migrationBuilder.DropColumn(
name: "Name",
table: "Customers");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
O EF Core geralmente não consegue saber quando a intenção é soltar uma coluna e criar uma nova (duas alterações separadas) e quando uma coluna deve ser renomeada. Se a migração acima for aplicada as-is, todos os nomes dos seus clientes serão perdidos. Para renomear uma coluna, substitua a migração gerada acima pelo seguinte:
migrationBuilder.RenameColumn(
name: "Name",
table: "Customers",
newName: "FullName");
Tip
O processo de scaffolding de migração avisa quando uma operação pode resultar em perda de dados (como eliminar uma coluna). Se vir esse aviso, certifique-se especialmente de revisar o código de migrações para garantir precisão.
Operações de dados
As migrações podem mover dados, bem como alterar o esquema. Escolha a operação com base em saber se os valores são conhecidos quando a migração é escrita:
- Use
InsertData,UpdateData, eDeleteDatapara valores e linhas fixos identificados por chaves explícitas. O EF Core traduz estas operações para SQL específico de cada fornecedor, pelo que também funcionam na geração de scripts e bundles. - Use
Sqlquando os novos valores têm de ser calculados a partir dos dados existentes da base de dados. A sintaxe SQL pode variar consoante o fornecedor; ExpandirMigrationBuilder.ActiveProviderquando necessário. - Defina uma operação de migração personalizada quando uma operação reutilizável necessita de geração SQL específica para o fornecedor.
Não use os tipos CLR atuais DbContext ou de entidade para mover dados numa migração. As migrações históricas devem continuar a compilar-se e a comportar-se da mesma forma depois de esses tipos serem alterados ou removidos.
Transformar dados existentes
Ao substituir as colunas, preserve os dados de origem até que o destino tenha sido preenchido:
- Adicione a coluna de destino como anulável.
- Preenche-o a partir das colunas existentes.
- Faça a coluna de destino obrigatória, se apropriado.
- Elimina as colunas de origem.
A migração seguinte implementa essa sequência para SQL Server e SQLite:
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
{
migrationBuilder.Sql(
"""
UPDATE [Customers]
SET [FullName] = [FirstName] + N' ' + [LastName];
""");
}
else if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.Sqlite")
{
migrationBuilder.Sql(
"""
UPDATE "Customers"
SET "FullName" = "FirstName" || ' ' || "LastName";
""");
}
else
{
throw new NotSupportedException(
$"Data migration is not implemented for provider {migrationBuilder.ActiveProvider}.");
}
migrationBuilder.AlterColumn<string>(
name: "FullName",
table: "Customers",
nullable: false,
oldClrType: typeof(string),
oldNullable: true);
migrationBuilder.DropColumn(
name: "FirstName",
table: "Customers");
migrationBuilder.DropColumn(
name: "LastName",
table: "Customers");
Adicione uma agência para cada fornecedor que a aplicação suporte. Lançar para um fornecedor desconhecido é mais seguro do que aplicar silenciosamente uma migração incompleta. Não construas SQL a partir de valores não confiáveis; o SQL de migração é executado com privilégios de alteração de esquema.
Algumas transformações não podem ser revertidas sem perder informação. Implemente Down apenas quando os valores originais puderem ser reconstruídos em segurança. Caso contrário, falham explicitamente e exigem a restauração dos dados de um backup como parte do procedimento de rollback.
Inserir dados fixos
InsertData Use quando as chaves e valores são conhecidos quando a migração é escrita:
migrationBuilder.InsertData(
table: "Countries",
columns: new[] { "CountryId", "Name" },
values: new object[,]
{
{ 1, "United States" },
{ 2, "Canada" }
});
O método correspondente Down deve chamar DeleteData com as mesmas chaves.
Atualizar dados fixos
UpdateData identifica uma linha pela sua chave e define uma ou mais colunas para valores fixos:
migrationBuilder.UpdateData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 1,
column: "Name",
value: "United States of America");
O Down método deve restaurar os valores anteriores.
Eliminar dados fixos
DeleteData também identifica linhas por chave:
migrationBuilder.DeleteData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 2);
Se a eliminação tiver de ser reversível, o Down método deve ser usado InsertData para restaurar todos os valores eliminados. Estas operações não consultam o estado atual da base de dados; Utilização Sql ou seeding em tempo de inicialização quando o comportamento depende dos dados existentes.
Alterações arbitrárias via SQL bruto
O SQL bruto também pode ser usado para gerenciar objetos de banco de dados dos quais o EF Core não está ciente. Para fazer isso, adicione uma migração sem fazer nenhuma alteração de modelo; uma migração vazia será gerada, que você poderá preencher com operações SQL brutas.
Por exemplo, a migração a seguir cria um procedimento armazenado do SQL Server:
migrationBuilder.Sql(
@"
EXEC ('CREATE PROCEDURE getFullName
@LastName nvarchar(50),
@FirstName nvarchar(50)
AS
SELECT @LastName + @FirstName;')");
Tip
EXEC é usado quando uma instrução deve ser a primeira ou a única em um lote SQL. Pode também ser usado para contornar erros de parser em scripts de migração idempotentes que podem ocorrer quando as colunas referenciadas não existem presentemente numa tabela.
Isso pode ser usado para gerenciar qualquer aspeto do seu banco de dados, incluindo:
- Procedimentos armazenados
- Pesquisa de Texto Completo
- Funções
- Triggers
- Views
Na maioria dos casos, o EF Core encapsulará automaticamente cada migração em sua própria transação ao aplicar migrações. Infelizmente, algumas operações de migração não podem ser realizadas dentro de uma transação em algumas bases de dados; Nestes casos, pode optar por não participar na transação passando suppressTransaction: true para migrationBuilder.Sql.
Note
No EF Core 9, o EF Core abrange todas as migrações pendentes com uma única transação por defeito (isto foi revertido no EF Core 10). Consulte a nota de alteração de última hora para mais detalhes.
Remover uma migração
Às vezes, você adiciona uma migração e percebe que precisa fazer alterações adicionais no seu modelo EF Core antes de aplicá-lo. Para remover a última migração, use este comando.
- da CLI do .NET
- Estúdio Visual
dotnet ef migrations remove
Depois de remover a migração, você pode fazer as alterações adicionais do modelo e adicioná-lo novamente.
Warning
Evite remover quaisquer migrações que já tenham sido aplicadas a bancos de dados de produção. Isso significa que você não poderá reverter essas migrações dos bancos de dados e poderá quebrar as suposições feitas pelas migrações subsequentes.
Se a migração fosse aplicada localmente
Para uma base de dados de desenvolvimento descartável, primeiro atualiza a base de dados para a migração anterior e depois remove a migração do projeto. Use 0 como alvo ao remover a primeira migração.
- da CLI do .NET
- Estúdio Visual
dotnet ef database update PreviousMigration
dotnet ef migrations remove
Alternativamente, --force executa ambos os passos:
dotnet ef migrations remove --force
Se a migração fosse aplicada a uma base de dados partilhada
Não apague uma migração que tenha sido aplicada a uma base de dados partilhada, de teste ou de produção. Normalmente, mantém a migração no projeto e adiciona uma nova migração corretiva. Se for necessário um rollback planeado, execute o rollback enquanto o código original de migração ainda estiver disponível e coordene a implementação da aplicação e da base de dados.
Remover uma migração antiga não aplicada
As ferramentas removem apenas a migração mais recente. Não apague uma migração do meio da sequência e edite manualmente o snapshot do modelo. Se a migração e todas as migrações seguintes forem não publicadas nem aplicadas, remova as migrações posteriores por ordem inversa, remova a migração indesejada e depois apoie novamente as alterações do modelo retido.
Se as migrações foram criadas em ramos diferentes, siga antes o fluxo de trabalho da árvore de migração divergente .
Listagem de migrações
Você pode listar todas as migrações existentes da seguinte maneira:
- da CLI do .NET
- Estúdio Visual
dotnet ef migrations list
Também pode inspecionar o estado da migração programaticamente:
var allMigrations = context.Database.GetMigrations();
var appliedMigrations = await context.Database.GetAppliedMigrationsAsync();
var pendingMigrations = await context.Database.GetPendingMigrationsAsync();
GetPendingMigrationsAsync compara as migrações no assembly de migrações configuradas com as migrações registadas na base de dados alvo. Não deteta alterações de modelos que não foram captadas numa migração; Use as alterações pendentes ao modelo, verifique abaixo para isso.
Verificação de alterações pendentes no modelo
Note
Esse recurso foi adicionado ao EF Core 8.0.
Às vezes, você pode querer verificar se houve alguma alteração de modelo feita desde a última migração. Isso pode ajudá-lo a saber quando você ou um colega de equipe esqueceu de adicionar uma migração. Uma maneira de fazer isso é usando esse comando.
dotnet ef migrations has-pending-model-changes
Você também pode executar essa verificação programaticamente usando context.Database.HasPendingModelChanges(). Isso pode ser usado para escrever um teste de unidade que falha quando você se esquece de adicionar uma migração.
Note
A partir do EF Core 9, chamar Migrate ou MigrateAsync com alterações pendentes do modelo gera uma exceção (event ID PendingModelChangesWarning). Consulte a documentação sobre a aplicação das migrações e a nota sobre a alteração incompatível para obter mais informações.
Redefinição de todas as migrações
Em alguns casos extremos, pode ser necessário remover todas as migrações e começar de novo. Isso pode ser feito facilmente excluindo sua pasta Migrações e descartando seu banco de dados; Nesse ponto, você pode criar uma nova migração inicial, que conterá todo o esquema atual.
Também é possível redefinir todas as migrações e criar uma única sem perder seus dados. Isto chama-se comprimir migrações e envolve algum trabalho manual. O EF Core atualmente não fornece um comando automático de squashing; ver dotnet/efcore#2174.
- Faça backup do seu banco de dados, caso algo dê errado.
- No banco de dados, exclua todas as linhas da tabela de histórico de migrações (por exemplo,
DELETE FROM [__EFMigrationsHistory]no SQL Server). - Exclua a sua pasta Migrações.
- Crie uma nova migração e gere um script SQL para ela (
dotnet ef migrations script). - Insira uma única linha no histórico de migrações, para registrar que a primeira migração já foi aplicada, uma vez que suas tabelas já estão lá. A inserção SQL é a última operação no script SQL gerado acima e é semelhante à seguinte (não se esqueça de atualizar os valores):
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
Warning
Qualquer de código de migração personalizado será perdida quando a pasta Migrações for excluída. Todas as personalizações devem ser aplicadas manualmente à nova migração inicial para serem preservadas.
Antes de comprimir, verifique se todas as bases de dados implementadas estão numa migração conhecida e faça backup dela. Novas bases de dados devem ser criadas a partir da nova migração inicial, enquanto as bases de dados existentes devem ter a migração de substituição registada sem executar operações de esquema já aplicadas. Teste ambos os caminhos antes da implementação.
Recursos adicionais
- Referência de ferramentas principais do Entity Framework - .NET CLI : Inclui comandos para atualizar, descartar, adicionar, remover e muito mais.
- Referência de ferramentas principais do Entity Framework - Console do Gerenciador de Pacotes no Visual Studio: Inclui comandos para atualizar, soltar, adicionar, remover e muito mais.