Home > Mobile >  Problem with HealthChecks.UI.SqlServer.Storage migrations
Problem with HealthChecks.UI.SqlServer.Storage migrations

Time:10-25

I'm trying to use Healthchecks UI in my asp.net core application with SqlServer.Storage for history purposes. It works with InMemoryStorage (without history part, of course).

So, Startup.cs code is like this:

services.AddHealthChecks()
    .AddHangfire(...)
    .AddDbContextCheck<...>("Database")
    .AddAzureBlobStorage(...)
    .AddProcessAllocatedMemoryHealthCheck(...)
    .AddCheck(...);

services
    .AddHealthChecksUI(settings =>
    {
        settings.SetEvaluationTimeInSeconds(...);
        settings.SetMinimumSecondsBetweenFailureNotifications(...);
        settings.MaximumHistoryEntriesPerEndpoint(...);
    })
    .AddSqlServerStorage(Configuration.GetConnectionString("..."));

later, additional configuration is in Configure method

Everything works when AddInMemoryStorage is used instead of AddSqlServerStorage. When AddSqlServerStorage is used, app crashes on startup, with

SqlException: Invalid object name 'Configurations'.

Sure, SQL tables are missing, but I cannot force [migration from nuget package to be applied to database.

Of course, I could copy/paste migration or create tables in database but I would like to skip that because of future changes and keeping code clean.

Can someone point me in right direction to solve this? Thanks

CodePudding user response:

I've managed to solve it. Since migrations weren't applied to database, I ran them in Main like this.

var app = CreateHostBuilder(args).Build();
//run heaalthchecksui migrations
using (var scope = app.Services.CreateScope())
{
    var healthChecksDb = scope.ServiceProvider.GetRequiredService<HealthChecksDb>();
    healthChecksDb.Database.Migrate();
}

app.Run();

So, maybe that workouround could help someone with similar problem.

CodePudding user response:

In Configure:

using IServiceScope scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope();

using HealthChecksDb healthChecksDb = scope.ServiceProvider.GetRequiredService<HealthChecksDb>();

healthChecksDb.Database.Migrate();

In ConfigureServices:

// build an intermediate service provider
ServiceProvider serviceProvider = services.BuildServiceProvider();            
try
{
    using HealthChecksDb healthChecksDb = serviceProvider.GetRequiredService<HealthChecksDb>();
    healthChecksDb.Database.Migrate();
        
}
finally
{ 
    serviceProvider.Dispose(); 
}
  • Related