DbMigrator.GetPendingMigrations() always empty

5k Views Asked by At

I'm using the DbMigrator class to get a list of pending migrations. For some reason it returns no items even though there are pending migrations. Am i missing a step?

var configuration = new Migrations.Configuration();
configuration.TargetDatabase = new DbConnectionInfo("MyDatabase");

var migrator = new DbMigrator(configuration);
var migs = migrator.GetPendingMigrations().ToList();
Console.WriteLine(migrator.GetPendingMigrations().ToString());

I thought it might be the connection string but what's interesting is that migrator.GetDatabaseMigrations() returns the correct list of migrations already applied to the db.

3

There are 3 best solutions below

0
On

I arrived at his question when trying to solve this in Entity framework core. Posting how I fixed it in case someone else also randomly gets to this question trying to solve this.

This is the solution on how to fix this in EF Core.

I added this Extension method to my code

public static IApplicationBuilder MigrateDatabase(this IApplicationBuilder app, IServiceScopeFactory scopeFactory)
{
    using (var scope = scopeFactory.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        db.Database.EnsureCreated(); // this was my problem. If the database was missing, then the migrations were never applied.

        var migrations = db.Database.GetPendingMigrations();
        if (migrations.Any())
            db.Database.Migrate();
    }

    return app;
}

And I call it in Startup.cs from

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceScopeFactory scopeFactory)
{
    // other things here
    app.MigrateDatabase(scopeFactory);
}
3
On

The same happened to me and the reason was that I was working in a different assembly. In that case, you need to specify the assembly and namespace that contains your migrations:

config.MigrationsAssembly = Assembly.GetAssembly(typeof([One of your migration classes]));
config.MigrationsNamespace = "[Namespace containing your migrations]";
1
On

I have same problem too, and after a week of research and read .Net source finally find solution. If you working in a different assembly, you mus set configuration assembly information completely like this:

    public void UpdateDatabaseToLatestVersion()
    {
        var configuration = new DbMigrationsConfiguration();
        var type = GetType();

        configuration.MigrationsAssembly = type.Assembly;
        configuration.TargetDatabase = new DbConnectionInfo(connectionString, "System.Data.SqlClient");
        configuration.MigrationsNamespace = type.Namespace + ".Migrations";
        configuration.ContextKey = type.Namespace + ".Migrations.Configuration";
        configuration.ContextType = type;
        var migrator = new DbMigrator(configuration);

        migrator.Update();
     }

This code is in DbContextBase class, All DbContext in my project inherit DbContextBase. DbContextBase is abstract and it is located in another assembly. When called UpdateDatabaseToLatestVersion from each DbContext, var type = GetType(); return inherited DbContext type.