DbContext未配置数据库提供程序问题排查(.NET仓储模式+Blazor)
问题分析与解决方案:DbContext未配置数据库提供商错误
错误根源
你的代码存在两处关键问题,导致DbContext无法获取正确的数据库配置:
UnitOfWork手动实例化无参构造的DbContext
在UnitOfWork类中,你直接通过new QualityAssuranceDbContext()创建上下文实例,调用的是无参构造函数。而你在Program.cs中配置的是带DbContextOptions参数的构造逻辑,这个手动new出来的上下文根本没有绑定任何数据库提供商配置。控制器手动实例化QualityAssuranceService
控制器中通过new QualityAssuranceService()创建服务实例,完全绕过了依赖注入容器。这导致服务内部使用的UnitOfWork也不是容器管理的实例,自然无法获取到已配置的DbContext。
修正步骤
1. 修改UnitOfWork,通过构造注入DbContext
将UnitOfWork改为从依赖注入容器获取DbContext,而非手动实例化:
public class UnitOfWork : IUnitOfWork { private readonly QualityAssuranceDbContext _context; private IBaseRepository<Aspect> _aspects; // 构造注入容器中已配置的DbContext public UnitOfWork(QualityAssuranceDbContext context) { _context = context; } public IBaseRepository<Aspect> Aspects => _aspects ??= new BaseRepository<Aspect>(_context); public void Dispose() { _context.Dispose(); GC.SuppressFinalize(this); } public async Task Save(HttpContext httpContext) { //DO STUFF } }
2. 修改控制器,通过构造注入QualityAssuranceService
让控制器从依赖注入容器获取服务实例:
public class QualityAssuranceController : ControllerBase { private readonly QualityAssuranceService _qualityAssuranceService; // 构造注入服务 public QualityAssuranceController(QualityAssuranceService qualityAssuranceService) { _qualityAssuranceService = qualityAssuranceService; } [HttpGet] public async Task<IActionResult> GetAspects(bool includeDeleted = false) { var claimsPrincipal = User; var schoolId = claimsPrincipal.FindFirst(c => c.Type == "schoolId"); if (schoolId != null) { var aspects = await _qualityAssuranceService.GetAspects(int.Parse(schoolId.Value), false); var aspectsDto = (from aspect in aspects select new AspectDto() { Name = aspect.Name, }).ToList(); return Ok(aspectsDto); } else { return NoContent(); } } }
3. 注册QualityAssuranceService到依赖注入容器
在Program.cs中添加服务注册(根据业务需求选择合适的生命周期):
builder.Services.AddTransient<QualityAssuranceService>();
4. 可选:移除DbContext的无参构造函数(推荐)
为了避免后续误操作,删除DbContext的无参构造,强制必须通过依赖注入获取实例:
public class QualityAssuranceDbContext : DbContext { public QualityAssuranceDbContext(DbContextOptions<QualityAssuranceDbContext> options) : base(options) { } // 移除无参构造 // public QualityAssuranceDbContext() // { // } public DbSet<Aspect> Aspects { get; set; } //PLUS OTHER ENTITIES REDACTED FOR BREVITY }
核心原理说明
依赖注入容器会负责管理所有已注册服务的生命周期,并且在创建DbContext时自动传入你在Program.cs中配置的DbContextOptions(包含SQL Server连接字符串和提供商信息)。手动实例化对象会完全绕过这个机制,导致上下文没有任何数据库配置,最终触发错误。
内容的提问来源于stack exchange,提问作者Hannah Hayes
相关产品推荐
相关产品推荐

