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();
}
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