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

使用.NET 6+CQRS+MediatR搭建分层API时EF Core迁移报错求助

解决.NET 6分层API中EF Core无法创建DbContext实例的迁移问题

问题重现

执行首次EF Core迁移时触发异常:
Unable to create an object of type 'WorldCupApiDbContext'

场景:使用.NET 6结合CQRS与MediatR搭建分层Web API,已尝试指定MigrationsAssembly配置,但问题未解决。


相关代码

Program.cs

using System.Reflection;
using MediatR;
using Microsoft.EntityFrameworkCore;
using WorldCupApi.Application.Handler.QueryHandler;
using WorldCupApi.Repository.Entities;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContextPool<WorldCupApiDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});

builder.Services.AddMediatR(typeof(GetGroupQueryHandler).GetTypeInfo().Assembly);

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

WorldCupApiDbContext.cs

using Microsoft.EntityFrameworkCore;

namespace WorldCupApi.Repository.Entities;

public class WorldCupApiDbContext : DbContext
{
    public WorldCupApiDbContext(DbContextOptions<WorldCupApiDbContext> options) : base(options)
    {
        
    }
    
    //entities
    public DbSet<Group> Groups { get; set; }
    public DbSet<Team> Teams { get; set; }
}

已尝试的配置修改

builder.Services.AddDbContextPool<WorldCupApiDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), 
        b=> b.MigrationsAssembly("WorldCupApi.Repository"));
});

解决方案

1. 显式指定迁移命令的项目参数

分层架构下,EF Core工具无法自动识别启动项目和DbContext所在项目,需要在命令行中明确指定:

# 替换为你的实际项目名称
dotnet ef migrations add InitialCreate --project WorldCupApi.Repository --startup-project WorldCupApi.Web

2. 实现IDesignTimeDbContextFactory(官方推荐方案)

在WorldCupApi.Repository项目中添加工厂类,让迁移工具能正确初始化DbContext:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace WorldCupApi.Repository.Entities;

public class WorldCupApiDbContextFactory : IDesignTimeDbContextFactory<WorldCupApiDbContext>
{
    public WorldCupApiDbContext CreateDbContext(string[] args)
    {
        // 加载Web项目的配置文件,确保连接字符串一致
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("../WorldCupApi.Web/appsettings.json") // 根据实际项目路径调整
            .Build();

        var optionsBuilder = new DbContextOptionsBuilder<WorldCupApiDbContext>();
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
            b => b.MigrationsAssembly("WorldCupApi.Repository"));

        return new WorldCupApiDbContext(optionsBuilder.Options);
    }
}

3. 验证连接字符串配置

确保Web项目的appsettings.json中存在有效连接字符串:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=WorldCupApiDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

4. 临时方案:添加无参构造函数(不推荐生产环境使用)

迁移工具在部分场景下会尝试使用无参构造函数创建实例,可临时添加:

public class WorldCupApiDbContext : DbContext
{
    // 保留原有依赖注入构造函数
    public WorldCupApiDbContext(DbContextOptions<WorldCupApiDbContext> options) : base(options)
    {
    }

    // 仅用于迁移的无参构造函数
    protected WorldCupApiDbContext()
    {
    }

    // ... DbSet定义
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:15:32