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

EF Core执行update-database报未找到引用设计时服务如何解决

问题场景

在包管理器控制台执行update-database -verbose命令时,SQL Server未生成预期数据库对象,命令末尾返回如下日志:

Using context 'TutoringContext'.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding design-time services referenced by assembly 'LakeTutoringWebsite'...
Finding design-time services referenced by assembly 'LakeTutoringWebsite'...
No referenced design-time services were found.
Finding IDesignTimeServices implementations in assembly 'LakeTutoringWebsite'...
No design-time services were found.

当前项目基础信息:

  • 框架版本:ASP.NET Core 3.1
  • 已安装依赖:6.0.0版本System.Configuration.Configuration包
  • 已通过依赖注入完成TutoringContext的服务注册,现有代码如下:
public class Startup
{
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddDbContext<TutoringContext>(options =>
               options.UseSqlServer(Configuration.GetConnectionString("LakeTutoringDatabase")));
        }
}

public class Program
{
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
}

public class TutoringContext : IdentityDbContext<IdentityUser>
{
    public DbSet<Comment> Comments { get; set; }

    public TutoringContext(DbContextOptions<TutoringContext> options) : base(options)
    {
    }

}

核心限制:已知DesignTimeDbContextFactory可解决该类迁移问题,但常规实现要求无参构造,无法传入IConfiguration读取配置文件中的连接字符串,需要在不硬编码连接字符串的前提下完成数据库迁移。

解决方案

以下两种方案都不需要硬编码连接字符串,可根据项目情况选择:

  • 方案一:实现可自动加载配置的DesignTimeDbContextFactory
    不需要依赖无参构造,直接在工厂方法内部手动构建配置对象,和运行时逻辑保持一致读取appsettings.json中的连接串即可,不需要修改现有DI注册代码,实现如下:

    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Design;
    using Microsoft.Extensions.Configuration;
    using System.IO;
    
    public class TutoringContextFactory : IDesignTimeDbContextFactory<TutoringContext>
    {
        public TutoringContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                // 需要读取环境变量配置时可放开下方注释
                // .AddEnvironmentVariables()
                .Build();
    
            var optionsBuilder = new DbContextOptionsBuilder<TutoringContext>();
            optionsBuilder.UseSqlServer(configuration.GetConnectionString("LakeTutoringDatabase"));
    
            return new TutoringContext(optionsBuilder.Options);
        }
    }
    

    将该类放在TutoringContext所在项目的根目录即可,EF Core设计时工具会自动扫描识别,不需要额外注册。需要提前将appsettings.json的文件属性设置为如果较新则复制,避免迁移执行时找不到配置文件。

  • 方案二:复用现有应用宿主的DI容器(无需编写额外工厂类)
    EF Core 3.1的设计时工具原生支持从ASP.NET Core启动流程中自动获取已注册的DbContext,触发当前报错的最常见原因是项目未安装对应版本的设计时包。先通过NuGet为项目安装3.1.x版本的Microsoft.EntityFrameworkCore.Design包,注意包版本必须和项目EF Core运行时版本、ASP.NET Core框架版本对齐,禁止安装6.x及以上版本避免兼容性冲突。安装完成后重启Visual Studio,重新执行update-database命令即可。工具会自动调用现有Program类中的CreateHostBuilder方法构建完整宿主,直接从DI容器中读取已经配置好连接字符串的TutoringContext实例,全程不需要修改业务代码。

注意:当前安装的6.0.0版本System.Configuration.Configuration是.NET Framework体系下的配置组件,和ASP.NET Core 3.1采用的Microsoft.Extensions.Configuration配置体系不兼容,不要用它读取Core项目的配置文件,避免出现版本冲突或配置读取失败问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:12:22