【问题标题】:Hangfire .NET Core database does not exist - PrepareSchemaIfNecessaryHangfire .NET Core 数据库不存在 - PrepareSchemaIfNecessary
【发布时间】:2020-03-13 20:35:23
【问题描述】:

我有一个托管在 docker 映像上的 .NET Core Web 应用程序。此应用程序使用托管在云数据库服务上的 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 管道中,我们希望首先构建和运行应用程序,然后在数据库服务上应用迁移脚本,因此在启动应用程序时我们没有可用的数据库。

【问题讨论】:

    标签: .net asp.net-core .net-core hangfire


    【解决方案1】:

    如果数据库不存在,您可以在 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();
                }
            }
        }
    }
    

    然后在Configure中使用:

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

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

    【讨论】:

      【解决方案2】:

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

      在配置服务中: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();
          }`
      

      JobStorage.Current 应该在注入 IBackgroundJobClient 之前设置,所以 我们不能在 Configure 中注入 IBackgroundJobClient

      另一种解决方案:-

      简单地使用另一个重载的 services.AddHangfire,如下所示

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-26
        相关资源
        最近更新 更多