You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DbContext未配置数据库提供程序问题排查(.NET仓储模式+Blazor)

问题分析与解决方案:DbContext未配置数据库提供商错误

错误根源

你的代码存在两处关键问题,导致DbContext无法获取正确的数据库配置:

  1. UnitOfWork手动实例化无参构造的DbContext
    在UnitOfWork类中,你直接通过new QualityAssuranceDbContext()创建上下文实例,调用的是无参构造函数。而你在Program.cs中配置的是带DbContextOptions参数的构造逻辑,这个手动new出来的上下文根本没有绑定任何数据库提供商配置。

  2. 控制器手动实例化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:43:22