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

EF Core 7.0.2代码优先迁移时DbContext未配置数据库提供程序错误

EF Core 7迁移报错“未配置数据库提供程序”的解决办法

执行迁移命令 dotnet ef migrations add InitialCreate --project PreventionCyber.DAL --startup-project PreventionCyber.Web 时,触发以下错误:

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.

问题分析及修复方案

1. 服务注册顺序错误

你在Program.cs中先执行了 var app = builder.Build();,之后才注册DbContext。但 builder.Build() 会完成服务容器的构建,后续的服务注册不会被纳入容器配置,导致EF迁移工具无法识别DbContext的数据库配置。

修复:将DbContext注册代码移到 builder.Build() 之前。

2. DbContext注册方式不当

使用 AddDbContext<DbContext, PCDbContext> 是间接注册基类DbContext的实现,但EF迁移工具会直接查找PCDbContext的服务注册,这种写法可能导致工具无法匹配到正确的配置。

修复:直接注册PCDbContext类型。

3. 保留无参构造函数风险

PCDbContext中存在无参构造函数,EF在某些场景下会优先使用这个构造函数实例化DbContext,而该构造函数没有配置数据库提供程序,从而触发错误。

修复:移除无参构造函数,强制使用带配置参数的构造函数。

修改后的代码

Program.cs

using Microsoft.EntityFrameworkCore;
using PreventionCyber.DAL.Context;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// 调整注册顺序,并直接注册PCDbContext
builder.Services.AddDbContext<PCDbContext>(options
    => options.UseSqlServer(builder.Configuration.GetConnectionString("PreventionCyber")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

PCDbContext.cs

using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore;
using PreventionCyber.DAL.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PreventionCyber.DAL.Context
{
    public class PCDbContext : DbContext
    {
        // 移除无参构造函数,强制使用带配置的构造函数
        public PCDbContext(DbContextOptions<PCDbContext> options): base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (var entity in modelBuilder.Model.GetEntityTypes())
            {
                // Renommage clé primaire
                entity.GetProperty("Id")
                    ?.SetColumnName($"{entity.ClrType.Name}Id");
            }
        }

        public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
        {
            OnBeforeSaving();
            return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
        }

        private void OnBeforeSaving()   
        {
            var entries = ChangeTracker.Entries();

            foreach (var entry in entries)
            {
                if (entry.Entity is BaseEntity trackable)
                {
                    var now = DateTime.UtcNow;
                    var user = GetCurrentUser();

                    switch (entry.State)
                    {
                        case EntityState.Modified:
                            trackable.ModifieLe = now;
                            trackable.ModifiePar = user;
                            break;

                        case EntityState.Added:
                            trackable.CreeLe = now;
                            trackable.CreePar = user;
                            trackable.ModifieLe = now;
                            trackable.ModifiePar = user;
                            break;
                    }
                }
            }
        }

        private string GetCurrentUser()
        {
            return "UserName"; // TODO implement your own logic
        }
    }
}

额外说明

使用 builder.Configuration.GetConnectionString("PreventionCyber") 替代 GetValue<string> 是更规范的写法,它专门用于读取配置文件中ConnectionStrings节点下的内容。

内容的提问来源于stack exchange,提问作者Nathan Trouillet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:50:30