Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Conforme 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, primeiro você deve instalar as ferramentas de linha de comando do EF Core.
Tip
Caso o DbContext esteja em um assembly diferente do projeto de inicialização, você poderá especificar explicitamente o projeto de destino e o projeto de 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:
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 CreatedTimestampna entidade Blog.
Três arquivos são adicionados ao seu projeto no diretório Migrações :
-
XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.cs-- O arquivo de migrações principal. Contém as operações necessárias para aplicar a migração (em
Up) e revertê-la (emDown). - XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.Designer.cs-- O arquivo de metadados de migrações. Contém informações usadas pelo 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ções e alterar o namespace manualmente. Novas migrações são criadas como paralelas à última migração. Como alternativa, você pode especificar o diretório em tempo de geração da seguinte maneira:
dotnet ef migrations add InitialCreate --output-dir Your/Directory
Note
Você também pode alterar o namespace independentemente do diretório usando --namespace.
Criar e aplicar uma migração em uma etapa
Note
Esse recurso foi adicionado ao EF Core 11.
O dotnet ef database update comando dá suporte à criação e à aplicação de uma migração em uma única etapa usando a opção --add . Isso usa o Roslyn para compilar a migração em runtime, permitindo cenários como .NET Aspire e aplicativos em contêineres em que o aplicativo não pode ser interrompido e recriado:
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
Esse comando estrutura uma nova migração com o nome especificado, compila-a usando Roslyn e a aplica imediatamente ao banco de dados. Os arquivos de migração ainda são salvos em disco para controle do código-fonte e recompilação futura.
Se nenhuma alteração de modelo pendente for detectada, o comando aplicará todas as migrações pendentes existentes sem criar uma nova.
Personalizar código de migração
Embora o EF Core geralmente crie migrações precisas, você sempre deve examinar o código e verificar se ele corresponde à alteração desejada; em alguns casos, é até necessário fazer isso.
Renomeações de coluna
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 é remover uma coluna e criar uma nova (duas alterações separadas) e quando uma coluna deve ser renomeada. Se a migração acima for aplicada como está, 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 da migração avisa quando uma operação puder resultar em perda de dados (como o descarte de uma coluna). Se você vir esse aviso, tenha especial cuidado ao revisar o código de migrações para garantir a precisão.
Operações de dados
As migrações podem mover dados, bem como alterar o esquema. Escolha a operação com base em se os valores são conhecidos quando a migração é gravada:
- Use
InsertData,UpdateDataeDeleteDatapara valores fixos e linhas identificadas por chaves explícitas. O EF Core converte essas operações em SQL específico do provedor, portanto, elas também funcionam ao gerar scripts e pacotes. - Use
Sqlquando os novos valores precisarem ser calculados com base nos dados de banco de dados existentes. A sintaxe do SQL pode ser diferente por provedor; ramificar quandoMigrationBuilder.ActiveProvidernecessário. - Defina uma operação de migração personalizada quando uma operação reutilizável precisar da geração de SQL específica do provedor.
Não use os tipos CLR atuais DbContext ou de entidade para mover dados em uma migração. As migrações históricas devem continuar a compilar e se comportar da mesma forma depois que esses tipos forem alterados ou removidos.
Transformar dados existentes
Ao substituir colunas, preserve os dados de origem até que o destino seja preenchido:
- Adicione a coluna de destino como anulável.
- Preencha-o das colunas existentes.
- Torne a coluna de destino necessária, se apropriado.
- Solte as colunas de origem.
A migração a seguir 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 um branch para cada provedor compatível com o aplicativo. Gerar para um provedor desconhecido é mais seguro do que aplicar silenciosamente uma migração incompleta. Não crie SQL com base em 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ções. Implemente Down somente quando os valores originais puderem ser reconstruídos com segurança. Caso contrário, falhe explicitamente e exija a restauração dos dados de um backup como parte do procedimento de reversão.
Inserir dados fixos
Use InsertData quando as chaves e os valores forem conhecidos quando a migração for gravada:
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 por sua chave e define uma ou mais colunas como 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.
Excluir dados fixos
DeleteData também identifica linhas por chave:
migrationBuilder.DeleteData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 2);
Se a exclusão precisar ser reversível, o Down método deverá ser usado InsertData para restaurar cada valor excluído. Essas operações não consultam o estado atual do banco de dados; usar Sql ou propagar tempo de inicialização quando o comportamento depende dos dados existentes.
Alterações arbitrárias por meio do SQL bruto
O SQL bruto também pode ser usado para gerenciar objetos de banco de dados que 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ê pode 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 apenas uma em um lote SQL. Ele também pode ser usado para contornar erros de analisador em scripts de migração idempotentes que podem ocorrer quando colunas referenciadas não existem atualmente em uma tabela.
Isso pode ser usado para gerenciar qualquer aspecto do banco de dados, incluindo:
- Procedimentos armazenados
- Pesquisa de Texto Completo
- Functions
- 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 executadas em uma transação em alguns bancos de dados; para esses casos, você pode recusar a 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 padrão (isso foi revertido no EF Core 10). Consulte a nota de alteração significativa para obter detalhes.
Remover uma migração
Às vezes, você adiciona uma migração e percebe que precisa fazer alterações adicionais no modelo do EF Core antes de aplicá-la. Para remover a última migração, use este comando.
dotnet ef migrations remove
Depois de remover a migração, você pode fazer as alterações adicionais do modelo e adicioná-la novamente.
Warning
Evite remover as migrações que já foram aplicadas aos bancos de dados de produção. Isso significa que você não poderá reverter essas migrações dos bancos de dados e pode quebrar as suposições feitas pelas migrações subsequentes.
Se a migração foi aplicada localmente
Para um banco de dados de desenvolvimento descartável, primeiro atualize o banco de dados para a migração anterior e remova a migração do projeto. Use 0 como destino ao remover a primeira migração.
dotnet ef database update PreviousMigration
dotnet ef migrations remove
Como alternativa, --force executa as duas etapas:
dotnet ef migrations remove --force
Se a migração foi aplicada a um banco de dados compartilhado
Não exclua uma migração que tenha sido aplicada a um banco de dados compartilhado, de teste ou de produção. Normalmente, mantenha a migração no projeto e adicione uma nova migração corretiva. Se uma reversão planejada for necessária, execute a reversão enquanto o código de migração original ainda estiver disponível e coordene a implantação do aplicativo e do banco de dados.
Remover uma migração desaplicada mais antiga
As ferramentas removem apenas a migração mais recente. Não exclua uma migração do meio da sequência e edite manualmente o instantâneo do modelo. Se a migração e cada migração após ela não for publicada e desaplicada, remova as migrações posteriores em ordem inversa, remova a migração indesejada e, em seguida, faça scaffold das alterações de modelo retidas novamente.
Se as migrações foram criadas em ramificações diferentes, siga o fluxo de trabalho de árvore de migração divergente .
Como listar migrações
Você pode listar todas as migrações existentes da seguinte maneira:
dotnet ef migrations list
Você também pode inspecionar o estado de 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 registradas no banco de dados de destino. Ele não detecta alterações de modelo que não foram capturadas em uma migração; use a verificação de alterações de modelo pendentes abaixo para isso.
Verificação de alterações pendentes no modelo
Note
Esse recurso foi adicionado no EF Core 8.0.
Às vezes, talvez você queira 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 gravar um teste de unidade que falha quando você esquece de adicionar uma migração.
Note
A partir do EF Core 9, chamar Migrate ou MigrateAsync com alterações de modelo pendentes gera uma exceção (ID PendingModelChangesWarningdo evento). Consulte a documentação sobre a aplicação de migrações e a nota sobre alterações que quebram a compatibilidade para obter mais informações.
Redefinindo todas as migrações
Em alguns casos extremos, pode ser necessário remover todas as migrações e recomeçar. 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. Isso é chamado de migrações de esmagamento e envolve algum trabalho manual. Atualmente, o EF Core não fornece um comando de esmagamento automatizado; consulte dotnet/efcore#2174.
- Faça backup do 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 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, já que suas tabelas já estão lá. O SQL de inserção é a última operação no script SQL gerado acima e é semelhante ao 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 código de migração personalizado será perdido quando a pasta Migrações for excluída. Todas as personalizações devem ser aplicadas à nova migração inicial manualmente para serem preservadas.
Antes de esmagar, verifique se cada banco de dados implantado está em uma migração conhecida e faça backup dele. Novos bancos de dados devem ser criados a partir da nova migração inicial, enquanto os bancos de dados existentes devem ter a migração de substituição registrada sem executar operações de esquema que já foram aplicadas. Teste os dois caminhos antes da implantação.
Recursos adicionais
- Referência de ferramentas do Entity Framework Core – CLI do .NET : Inclui comandos para atualizar, remover, adicionar, descartar e muito mais.
- Referência de ferramentas do Entity Framework Core – Console do Gerenciador de Pacotes no Visual Studio : inclui comandos para atualizar, excluir, adicionar, remover e muito mais.