.Net Core EF DBContext迁移执行失败 无法创建DbContext对象报错
问题场景
基于Clean Architecture(整洁架构)采用EF Code First模式开发时,通常实体模型存放在.Core项目,DbContext定义在.Infra或.Data项目内。创建数据库迁移时,打开开发者命令提示符切换到Infra项目目录,执行以下命令:
dotnet ef migrations add myDBInit --context MyDbContext --output-dir Migrations
执行命令后抛出如下错误:
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'MyDBContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'MyDBContext'. For the different patterns supported at design time, refer to EF Core official design-time documentation.
---> System.InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[CaseEscalation.Infra.MyDBContext]' while attempting to activate 'CaseEscalation.Infra.MyDBContext'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_4.b__13()
排查与解决方案
- 修正命令执行路径与参数
EF Core设计时工具默认会将当前执行目录的项目作为启动项目,尝试查找Program类中的CreateHostBuilder方法构建依赖注入容器,再从中解析DbContext实例。在Infra项目目录直接执行命令时,Infra类库本身没有Host启动配置,自然无法解析DbContext需要的Options参数。
正确执行方式是切换到你的Web/API入口项目(即正常配置了DbContext服务注入的启动项目)目录执行命令,通过--project参数指定DbContext所在的Infra项目路径:dotnet ef migrations add myDBInit --context MyDbContext --output-dir Migrations --project ../CaseEscalation.Infra/ - 添加设计时DbContext工厂(推荐整洁架构场景使用)
如果不想每次执行迁移都切换目录、指定启动项目,可以直接在Infra项目中实现IDesignTimeDbContextFactory<MyDbContext>接口,给EF Core设计时工具提供直接创建DbContext实例的逻辑,完全不需要依赖启动项目的服务配置。
在Infra项目根目录添加如下类:
添加完成后,EF Core工具会自动扫描到这个工厂实现,直接在Infra项目目录执行原迁移命令即可正常运行,不需要额外配置。public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext> { public MyDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); // 替换为你本地开发环境的数据库连接字符串 optionsBuilder.UseSqlServer("Server=.;Database=CaseEscalation;Trusted_Connection=True;TrustServerCertificate=True;"); return new MyDbContext(optionsBuilder.Options); } } - 检查基础配置正确性
- 确认启动项目和Infra项目都安装了
Microsoft.EntityFrameworkCore.DesignNuGet包,且所有EF Core相关包的版本号完全一致,版本不匹配会导致设计时服务加载失败。 - 检查MyDbContext的构造函数签名,必须接收泛型类型
DbContextOptions<MyDbContext>作为参数,不要使用非泛型的DbContextOptions类型,否则依赖注入容器无法正确匹配注入实例。
- 确认启动项目和Infra项目都安装了
内容的提问来源于stack exchange,提问作者Balaji V

