dotnet / dotnet/efcore

Add safeguard for MigrateAsync with targetMigration

Open
#34,819 5 comments 0 reactions 0 assignees View on GitHub
area-migrations customer-reported needs-design
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

We are using the following code to run each migration one by one, so we can better determine which migration failed:

```
var pendingMigrations = await dbContext.Database.GetPendingMigrationsAsync(cancellationToken);

var migrator = dbContext.Database.GetInfrastructure().GetRequiredService();

foreach (string migration in pendingMigrations)
{
logger.LogInformation($"Applying migration '{migration}'...");

await migrator.MigrateAsync(migration, cancellationToken);
}
```

Recently when we deployed an application we noticed an unfamiliar behaviour. A field disappeared and was gone after the migrations were executed.
It turned out that for one migration, the Down-Migration was called, because that migration was already deployed and had a higher timestamp in the filename than the pending migrations. This happened because the migration was added on a branch that was going live, while on a dev branch already new migrations were added before.
So when the first pending migration was executed via IMigrator.MigrateAsync, the down migration of that already deployed migration was called. As far as I understand this is to make sure that the migrations always run on the "correct" state of the database.
In our case this caused an issue because the Down-Migration was called, but the Up-Migration was never called again. I assume this is because we use the migrator to explicitly execute migrations and it doesn't know when the last migration was done. I also assume this works correctly with the usual Database.MigrateAsync() method.

So my questions are:
- Is it even safe to use IMigrator.MigrateAsync, when it can implicitly call down migrations but in the end will never call the Up migration again?
- Is there a way we can ensure that the Up-Migration is executed in the end?
- Is this behaviour even documented somewhere? It took a lot of time to figure out why a field was deleted.

### Include provider and version information

EF Core version:
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11
IDE: Visual Studio 2022

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.