EF core use dbContext.Database.Migrate(); to execute migrations automatically after configuring UseSqlServer()

Viewed 524

I have created an extension method called AddSQLServer that is used in the Startup.cs / ConfigureServices that simply adds the dbContext to the ServiceCollection. I would like to run the migrations directly after initializing the dbContext.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    var connectionString = Configuration.GetConnectionString("Test");

    services.AddLogging(config =>
    {
         config.AddSqlServer(connectionString);
    }); 
}

Action method which configures the dbContext

public class MyProvider
{
     private readonly IServiceCollection serviceCollection;

     public MyProvider(IServiceCollection serviceCollection)
     {
         this.serviceCollection = serviceCollection;
     }

     public void AddSqlServer(string connectionString)
     {
         serviceCollection.AddDbContext<OutputDbContext>(config => config.UseSqlServer(connectionString));
         // somehow calling dbContext.Database.Migrate(); to run migrations 
     }
}
1 Answers

You don't need to run migrations when configuring services. You need to use HostedService for that and register it in Program.cs before registering your Startup. That way your migrations will be run by ASP.MVC Core engine before starting your application. It guarantees that when your application will be started all your migrations will be aplied. Program.cs will look something like this:

var host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
.ConfigureServices(service =>
{
    service.AddHostedService<HostedDbMigrationService>();
})
.ConfigureWebHostDefaults(x =>
{
    x.UseStartup<Startup>();
}).Build();

And create HostedDbMigrationService:

public class HostedDbMigrationService : IHostedService
{
    private readonly IDbContext _dbContext;

    public HostedDbMigrationService(IDbContext context)
    {
        _dbContext = context;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _dbContext.Database.Migrate();
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

In constructor you can access any registered dependencies. In StartAsync you can execute your migrations

Related