ASP.NET Core的 HealthCheck需要进行数据库迁移,但我搞不清楚它需要哪一个迁移
我的ASP.NET Core应用抛出这个异常,我还没想清楚该如何解决:
为警告 'Microsoft.EntityFrameworkCore.Migrations.PendingModelChangesWarning' 生成了一个错误:上下文 'HealthChecksDb' 的模型存在待处理的变更。在更新数据库之前请添加一个新的迁移。
我的代码本身没有上下文 HealthChecksDb,所以这一定是ASP.NET Core内部的问题。
但所谓的 "pending changes" 是什么?
- 我的代码没有上下文
HealthChecksDb,所以我猜这一定是ASP.NET Core内部的某些问题吧? - 我没有任何名为
HealthCheck的表 - 我也没有进行任何架构变更。
- 如果我
dotnet ef add来创建一个迁移,该迁移是空的(也是应该的)
我完全被拗住了。我甚至不知道在这儿该调查什么。
以下是我的代码摘录:
// From Main:
IHost host = CreateHostBuilder(args, log, appSettings, app).Build();
new Thread(() =>
{
host.Run();
}) {
IsBackground = true
}.Start(); /// <------- SOURCE OF STACKTRACE
// And now the function that the above code calls,
// which is where the problem probably really is:
public static IHostBuilder CreateHostBuilder(string[] args, ILogger log, MyAppSettings appSettings, MyApp myapp)
{
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
string port = Environment.GetEnvironmentVariable("MYPORT");
webBuilder.UseKestrel();
webBuilder.UseUrls($"http://*:{port}");
webBuilder.ConfigureServices((services) =>
{
string configString = $"Host=blah;Database=blah{1};Username=blah{2};Password=blah;Include Error Detail=True";
services.AddSingleton(myapp);
/// If I comment out these two AddHealthCheck calls,
/// the exception is not thrown (unsurprisingly).
services.AddHealthChecks()
.AddCheck("MyAppHealth", new HealthCheck(myapp));
services.AddHealthChecksUI()
.AddPostgreSqlStorage(configString);
services.AddControllers();
});
webBuilder.Configure(app =>
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks($"/myapp_health");
endpoints.MapHealthChecks($"/myapp_health_ui", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
endpoints.MapControllers();
});
});
})
.UseSerilog();
}
解决方案
我在全新设置下无法重现你的问题(我的复现尝试),但这里有一些想法(提供的代码不足以构成一个 Minimal, Reproducible Example):
所以这一定是ASP.NET Core的内部问题。
不,默认情况下ASP.NET Core并不使用任何数据库/EF Core上下文。这个问题似乎来自你正在使用的 Xabaril/AspNetCore.Diagnostics.HealthChecks 套件。至少据我所知,是提供所使用的 AddHealthChecksUI 和 AddPostgreSqlStorage 调用的那一组。
我的代码没有上下文
HealthChecksDb
它来自 HealthChecks.UI.Data 部分 - HealthChecksDb 源代码
我的推测是你在某处有包版本不匹配,因此才会抛出异常。PostgreSQL的迁移是从相应程序集 动态地设置 的:
builder.Services.AddDbContext<HealthChecksDb>(optionsBuilder =>
{
configureOptions?.Invoke(optionsBuilder);
optionsBuilder.UseNpgsql(connectionString, npgsqlOptionsBuilder =>
{
npgsqlOptionsBuilder.MigrationsAssembly("HealthChecks.UI.PostgreSQL.Storage");
configurePostgreOptions?.Invoke(npgsqlOptionsBuilder);
});
});
但这当前只是一个大胆的猜测,因为没有足够的信息来完全调查问题。
P.S.
你使用 HostBuilder 的设置和手动创建的线程对我来说有点不太符合惯例,但那是完全不同的话题。看起来你也缺少 MapHealthChecksUI 调用。