locked
Can Entity Framework migrations run before Hosted Service start? RRS feed

  • Question

  • User631154878 posted

    We have a .NET Core 5 Web application and we run our EF migrations as part of the application startup via the Startup.Configure(...) method.  I recently added a Hosted Service to the app and discovered, much to my disappointment, that the hosted service starts before the Migrations run.  Since the Hosted Service relies on changes made by migrations, the app crashed.

    Is there any way to run the migrations before hosted services start?

    Thanks

    Monday, February 22, 2021 8:38 PM

All replies

  • User475983607 posted

    Um Yeah, we cannot see your code.  We have no idea how the code works.  Can't you design the hosted service to handle the exception or check to see if the migration is complete before starting the main loop?  

    Monday, February 22, 2021 9:01 PM
  • User631154878 posted

    I'm not sure how my code would help.  I've described the problem.  Making my hosted service know about migrations seems like a hack and unnecessary coupling.   If I have to do that for every service that's a lot of code to maintain.  Aren't there some other hooks to allow the migrations to take place at an earlier point in the application's startup sequence?

    If it helps, this is what my Startup class looks like:

     public class Startup()
     {
        public static void ConfigureServices(IServiceCollection services)
        {
            services.AddHostedService<MyHostedService>();
        }
    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            using (var scope = app.ApplicationServices.CreateScope())
            { 
                ApplicationDbContext context = scope.ServiceProvider.GetService<ApplicationDbContext>();
                context.Database.Migrate(); 
            }
        }
    }



    Monday, February 22, 2021 10:15 PM
  • User475983607 posted

    You still did not provide the relevant code...

    Anyway, you can start the hosted service in the program.cs file after the configuration has been called and the pipeline is configured.

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio#ihostedservice-interface

        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    }).ConfigureServices(services =>
                    {
                        services.AddHostedService<MyHostedService>();
                    });
        }
    
        internal class MyHostedService : IHostedService
        {
            public Task StartAsync(CancellationToken cancellationToken)
            {
                throw new NotImplementedException();
            }
    
            public Task StopAsync(CancellationToken cancellationToken)
            {
                throw new NotImplementedException();
            }
        }

    Monday, February 22, 2021 11:01 PM
  • User631154878 posted

    What about doing something like this in Program.Main.  It seems to work but I don't know if there are any side effects.

        public class Program
        {
            public static void Main(string[] args)
            {
                IHost host = CreateHostBuilder(args).Build();
                IServiceProvider serviceProvider = host.Services;
    
                IServiceScopeFactory scopeFactory = serviceProvider.GetService<IServiceScopeFactory>();
    
                using (var scope = scopeFactory.CreateScope())
                {
                    ApplicationDbContext context = scope.ServiceProvider.GetService<ApplicationDbContext>();
                    context.Database.Migrate();
                }
                host.Run();
            }
    

    Monday, February 22, 2021 11:05 PM
  • User1312693872 posted

    Hi,DaceREm

    Yes, this way is right, and you can check the five side effects in the official site:

    https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/applying?tabs=dotnet-core-cli#apply-migrations-at-runtime

    Best Regards,

    Jerry Cai

    Thursday, February 25, 2021 8:36 AM