Hangfire.NET Core数据库不存在-PrepareSchemaIfNenecessary



我有一个.NET Core web应用程序,它托管在docker镜像上。该应用程序使用PostgreSQL,后者托管在云数据库服务上。

我们添加了一个Hangfire,它将使用与我们的主要应用程序相同的云数据库服务。

public void ConfigureServices(IServiceCollection services)
{
...
services.AddHangfire(x => x.UsePostgreSqlStorage(ConnectionString));
...
}

以及在配置方法中:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseHangfireServer();
app.UseHangfireDashboard();
...
}

现在,如果数据库服务不可用(或者数据库不存在(,那么启动应用程序就有问题。

我尝试使用:

services.AddHangfire(x => x.UsePostgreSqlStorage(ConnectionString, new PostgreSqlStorageOptions
{
PrepareSchemaIfNecessary = false
}));

但现在,一旦数据库服务启动并运行,我就无法创建数据库模式。我找不到Hangfire.PostgreSql的任何迁移脚本,所以我可以将它们与其他业务迁移一起推送。

我知道Hangfire.SqlServer有Install.sql脚本,我们可以用它创建数据库模式,但PostgreSql什么都没有。

在CI/CD管道中,我们希望首先构建和运行应用程序,然后在数据库服务上应用迁移脚本,因此在启动应用程序时没有可用的数据库。

我遇到了这个问题,所以我在调试中运行了我的应用程序,并完成了整个创建过程。

我的问题是,我需要创建一个模式,并授予用户创建更新删除等权限。

默认模式是hangfire,但您可以像那样更新它


config.UsePostgreSqlStorage(connectionString, new PostgreSqlStorageOptions()
{
InvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.FromMilliseconds(200),
DistributedLockTimeout = TimeSpan.FromMinutes(1),
PrepareSchemaIfNecessary = true,
SchemaName = ["Schema"]
});

希望能有所帮助。

如果数据库不存在,您可以在Startup.cs中使用hangfire服务器之前使用EF来应用迁移。

public void ApplyMigrations(AppDbContext context)
{
try
{
if (context.Database.GetPendingMigrations().Any())
{
context.Database.Migrate();
}
}
catch (Npgsql.PostgresException ex)
{
if (ex.SqlState == "42P07")
{
context.Database.EnsureDeleted();
if (context.Database.GetPendingMigrations().Any())
{
context.Database.Migrate();
}
}
}
}

然后在配置:中使用

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AppDbContext appDbContext,) 
{
...
ApplyMigrations(appDbContext);
app.UseHangfireServer();
app.UseHangfireDashboard();
... 
}

您还应该使用dotnet-ef工具创建这些迁移。

我遇到了同样的问题,下面是我的解决方案:-

在ConfigureServices:services.AddHangfire(config=> { });

在配置中:调用第一个ApplyAutomaticDatabaseMigration(serviceProvider);

然后:

JobStorage.Current = new PostgreSqlStorage(ConfigurationManager.Configuration.SqlConnectionString);
IBackgroundJobClient backgroundJobs = app.ApplicationServices.GetRequiredService<IBackgroundJobClient>();
`private void ApplyAutomaticDatabaseMigration(IServiceProvider serviceProvider)
{
ApplicationDbContext context = serviceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
context.Database.EnsureCreated();
}`

应在注入IBackgroundJobClient之前设置JobStorage.Current,以便我们无法在配置中注入IBackgroundJobClient

另一个解决方案:-

简单地使用另一个过载的服务。AddHangfire类似以下

services.AddHangfire((serviceProvider, config) =>
{
ApplyAutomaticDatabaseMigration(serviceProvider.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>());
config.UsePostgreSqlStorage(ConfigurationManager.Configuration.SqlConnectionString);
});

最新更新