Search code examples
c#entity-framework-corewebapihangfire

Create DB before add hangfire


I use Hangfire to work with reccuring jobs. Hangfire needs existing DB to work. I can apply DB migrations from DbContext or ServiceScope created from WebApplication, but hangfire throws exception on configuring service step. How I can programmly create DB using EFCore before add hangfire?

Add hangfire:

    builder.Services.AddHangfire(x => x
        .UseSimpleAssemblyNameTypeSerializer()
        .UseRecommendedSerializerSettings()
        .UsePostgreSqlStorage(builder.Configuration["HangfireConnection"]));
    builder.Services.AddHangfireServer(options =>
    {
        options.WorkerCount = 10;
    });

Ways that don't work:

    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) 
    {
        Database.Migrate();
    }
    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) 
    {
        Database.EnsureCreated();
    }
    using (var scope = app.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<TestDbContext>();
        context.Database.EnsureCreated();
    }
    using (var scope = app.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<TestDbContext>();
        context.Database.Migrate();
    }

Solution

  • I found a solution:

    var connString = builder.Configuration.GetConnectionString("ConnectionString")!;
    
    var connectionStringBuilder = new NpgsqlConnectionStringBuilder(connString);
    var databaseName = connectionStringBuilder.Database;
    connectionStringBuilder.Database = "postgres";
    
    
    using var connection = new NpgsqlConnection(connectionStringBuilder.ToString());
    connection.Open();
    
    using var checkCommand = new NpgsqlCommand($"SELECT 1 FROM pg_database WHERE datname='{databaseName}'", connection);
    var exists = (int?)checkCommand.ExecuteScalar() == 1;
    
    if (!exists)
    {
        using var command = new NpgsqlCommand($"CREATE DATABASE {databaseName};", connection);
        command.ExecuteNonQuery();
    }
    

    This creates the DB if not exists, it doesn't need EF. Only create the connection and command also you need the package Npgsql.EntityFrameworkCore.PostgreSQL