ASP.NET Core 注入DbContext时出现找不到AzureSql连接串的异常
异常触发原因
这个报错本质是依赖注入链解析失败,导致EF Core无法使用你预先配置的DbContextOptions,转而触发默认的连接串查找逻辑,最终抛出找不到AzureSql连接串的异常,具体原因有三个:
- 你没有在服务注册时添加
IHttpContextAccessor和IGetUserProvider的声明,依赖注入容器无法构造GetUserProvider实例,进而无法完成TimeSheetContext的实例化。 - 即使注册了服务,如果
IGetUserProvider的生命周期配置错误(比如设为Singleton),会和它依赖的Scoped生命周期的IHttpContextAccessor产生生命周期不匹配问题,同样会导致DI解析失败。 GetUserProvider构造函数中存在隐藏bug:查询Claim的条件x.Type == UserName里的UserName是当前类的未赋值属性,值为null,会导致永远取不到用户声明,后续可能引发其他业务错误。
另外你当前的全局查询过滤器写法也有问题:过滤器默认会在模型首次初始化时求值,只会保留第一次请求的branchFilter值,不会随后续请求的用户变化动态更新,达不到按当前用户过滤数据的目的。
解决方案
按照以下步骤修改即可:
- 在
Startup.cs的ConfigureServices方法中注册缺失的服务,注意生命周期配置:
// 注册IHttpContextAccessor services.AddHttpContextAccessor(); // 注册IGetUserProvider,使用和请求绑定的Scoped生命周期 services.AddScoped<IGetUserProvider, GetUserProvider>();
- 修复
GetUserProvider中的Claim查询逻辑,替换为正确的Claim类型:
// 示例用系统默认的用户名Claim类型,如果你用自定义Claim,替换为对应的字符串即可 UserName = accessor.HttpContext?.User.Claims.SingleOrDefault(x => x.Type == ClaimTypes.Name)?.Value;
- 修改
TimeSheetContext中的全局查询过滤器写法,让它可以动态获取当前实例的过滤值:
首先把branchFilter改为TimeSheetContext的公共属性,然后调整过滤器的写法:
// TimeSheetContext类中 public int branchFilter { get; set; } // OnModelCreating方法中 modelBuilder.Entity<Branch>().HasQueryFilter(b => b.ContractorCode == this.branchFilter);
内容的提问来源于stack exchange,提问作者Colin-G-Davidson
相关产品推荐
相关产品推荐

