EF Core从5升级至9后IIS应用池回收时触发DbContext未配置异常的问题求助
我们团队在多个业务系统里使用EF Core 5已经有相当长一段时间了,之前一直因为依赖关系的牵绊没敢升级。这次好不容易完成了版本升级,本地在Visual Studio里测试完全没问题,部署到IIS上初期也一切正常——网站能正常访问,数据库连接也没问题。
可一旦IIS回收了应用池,麻烦就来了,系统会直接抛出InvalidOperationException异常,具体信息如下:
System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, DbContextOptions contextOptions, DbContext context)
at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()
at Microsoft.EntityFrameworkCore.DbContext.get_Model()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityType() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityQueryable() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken)
at Beheer.Services.Dashboard.DashboardService.GetMaxDaysFromSettings() in D:\Agents\Agent.Morpheus_work\2\s\Back-end\Beheer.Services\Dashboard\DashboardService.cs:line 330
at Beheer.Services.Dashboard.DashboardService.GetRecentErrorLogs(Paging paging) in D:\Agents\Agent.Morpheus_work\2\s\Back-end\Beheer.Services\Dashboard\DashboardService.cs:line 137
at Beheer.Api.Controllers.DashboardController.GetRecentErrorLogs(Paging paging) in D:\Agents\Agent.Morpheus_work\2\s\Back-end\Beheer.Api\Controllers\DashboardController.cs:line 99
at lambda_method62(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
下面是相关的代码片段:
Program类代码
public static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment.EnvironmentName; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); config.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true); config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration .ReadFrom.AppSettings().Enrich.FromLogContext()); }
Startup类代码
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration["AppSettings:ConnectionString"]; services.AddDbContext<MyContext>(options => options.UseOracle(connectionString)); // .... } }
MyContext类代码
public class MyContext : DbContext { public MyContext() { } public MyContext(DbContextOptions<MyContext> options) : base(options) { } public virtual DbSet<SenderSettings> SenderSettings { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { } }
希望各位大佬能给点下一步排查的方向,非常感谢!
编辑更新:今天终于抽出时间深入排查了,先回复下大家的建议:
- @Jeff Zola:我们仔细看了EF的发布说明,但没找到能解释这个问题的内容;另外Oracle数据库不支持在连接字符串里加
Encrypt=False这个参数。 - @Jalpal Panchal:我试过移除DbContext的无参构造函数,但问题依然存在。
之后我尝试逐步升级Devart和EF的包,过程如下:
- 从EF 5升级到EF 6:一切正常
- 从EF 6升级到EF 7:没问题
- 从EF 7升级到EF 8:依然正常
- 从EF 8升级到EF 9:问题出现了....
最后我把项目从.NET 8升级到.NET 9之后,这个异常就消失了,之后也顺利完成了EF和Devart包的升级。
再次感谢大家的建议!
备注:内容来源于stack exchange,提问作者henkie




