You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET Core 5.0设计时迁移报错咨询:服务构造失败与工厂类问题

问题分析与解决方法

这个问题我之前也碰到过,核心原因是EF Core对设计时工厂类的构造函数有硬性要求——它必须拥有一个无参数的公共构造函数,因为EF在执行迁移命令时,会直接实例化这个工厂类,不会通过你的应用依赖注入容器来创建实例。你现在的DesignTimeTENANTSContextFactory只有一个带IDbConnectionString参数的构造函数,EF找不到无参构造来初始化它,这就是报错No parameterless constructor defined for type 'JobsLedger.API.DesignTimeTENANTSContextFactory'的根本原因。

另外还要注意:设计时工厂的核心目标是脱离应用的DI环境独立工作,所以你完全不需要在工厂里依赖任何DI注入的服务(比如你这里的IDbConnectionString),你的工厂代码里已经自己读取appsettings.json获取连接字符串了,那个注入的_connectionString其实是多余的。

具体解决步骤:

  1. 给工厂类添加无参数构造函数(或者直接移除带参数的构造函数):
    修改后的DesignTimeTENANTSContextFactory代码如下:
    public class DesignTimeTENANTSContextFactory : IDesignTimeDbContextFactory<TENANTSContext>
    {
        // 必须保留无参数公共构造函数,供EF实例化工厂
        public DesignTimeTENANTSContextFactory()
        {
        }
    
        public TENANTSContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
            var builder = new DbContextOptionsBuilder<TENANTSContext>();
            var connectionString = configuration.GetConnectionString("CatalogConnection");
            builder.UseSqlServer(connectionString);
            // 使用只带DbContextOptions的构造函数创建上下文
            return new TENANTSContext(builder.Options);
        }
    }
    
  2. 确保上下文的构造函数可访问
    你的TENANTSContext已经有一个带DbContextOptions<TENANTSContext>的公共构造函数,这个是EF设计时需要的,没问题;那个带HttpContext的构造函数是给应用运行时使用的,不影响迁移操作。
  3. 验证命令执行路径
    执行迁移命令时,确保你是在类库项目的目录下执行(或者通过-s参数正确指定Web项目作为启动项目),这样Directory.GetCurrentDirectory()才能正确找到appsettings.json文件。

额外说明:

设计时工厂的存在就是为了在不启动整个应用的情况下,让EF能够创建上下文实例来执行迁移、生成数据库脚本等操作。所以工厂内部必须自己处理所有依赖(比如读取配置、构建DbContextOptions),不能依赖应用的DI容器提供服务,否则就会出现你遇到的“服务无法构造”的连锁错误。

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

火山引擎 最新活动