Efcore: Migrations: Top level APIs for All/Applied/Pending

Created on 19 Jul 2016  路  8Comments  路  Source: dotnet/efcore

These APIs on DbContext.Database were useful in EF6. One example of where these would be useful is manually applying each migration so that you can give status to the user (#6038).

closed-fixed type-enhancement

Most helpful comment

For comparison:

EF6

``` C#
var migrator = new DbMigrator(new MigrationsConfiguration());

var all = migrator.GetLocalMigrations();
var applied = migrator.GetDatabaseMigrations();
var pending = migrator.GetPendingMigrations();

### EFCore (1.0.0)

``` C#
var migrationsAssembly = db.GetService<IMigrationsAssembly>();
var historyRepository = db.GetService<IHistoryRepository>();

var all = migrationsAssembly.Migrations.Keys;
var applied = historyRepository.GetAppliedMigrations().Select(r => r.MigrationId);
var pending = all.Except(applied);

All 8 comments

@rowanmiller I haven't dug into the migrator code yet, but when you tell the migrator to apply a migration does it check again to see if it's already been applied?

I have a scenario wherein a load-balanced asp.net core application may require each instance to run on its own time after deploying a new version but then either share the migrations workload between the instances, or at least allow one of the instances to take ownership of the migrations by updating a database flag.

@rdefreitas the code I shared in the previous issue migrator.Migrate(targetMigration: pending[i]); isn't saying to apply a specific migration, it's saying to apply all pending migrations up to (and including) the one specified. Because the specified migration was being incremented by one on each iteration, it was applying just a single migration. Given that, the answer is yes, it will skip the migration if it is already applied.

These APIs on DbContext.Database were useful in EF6.

Huh? :confused: We had APIs on DbMigrator, but never off DbContext.Database AFAIK.

@bricelam I think you are right.

I think the general idea here is that it was easy to create a Migrator in EF6, which made it easy to do these things. It's also pretty easy to get a Migrator in EF Core, although very undiscoverable:

C# var migrator = context.GetService<IMigrator>();

But then once you get the Migrator it only has Migrate and GenerateSql.

So, regardless of what the actual API was in EF6, we want to make it easier to do these additional things in EF Core in whatever way makes sense for EF Core.

For comparison:

EF6

``` C#
var migrator = new DbMigrator(new MigrationsConfiguration());

var all = migrator.GetLocalMigrations();
var applied = migrator.GetDatabaseMigrations();
var pending = migrator.GetPendingMigrations();

### EFCore (1.0.0)

``` C#
var migrationsAssembly = db.GetService<IMigrationsAssembly>();
var historyRepository = db.GetService<IHistoryRepository>();

var all = migrationsAssembly.Migrations.Keys;
var applied = historyRepository.GetAppliedMigrations().Select(r => r.MigrationId);
var pending = all.Except(applied);

The scenarios in this issue overlap with with those of issue #577

We are using migrations against SQL Azure which requires a retry. We also need the progress of which migration it is on. This would be great to add to the framework. For now, I have done a workaround as above.

Was this page helpful?
0 / 5 - 0 ratings