执行dotnet ef迁移命令时DbContext实例创建失败求助
跟随GraphQL教程学习,执行命令 dotnet ef migrations add AddPlatformToDb 时触发以下错误:
Unable to create a 'DbContext' of type ''. The exception 'Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[CommanderGQL.Data.AppDbContext]' while attempting to activate 'CommanderGQL.Data.AppDbContext'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
项目相关文件内容如下:
CommanderGQL.csproj
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="GraphQL.Server.Ui.Voyager" Version="7.7.1" /> <PackageReference Include="HotChocolate.AspNetCore" Version="13.9.0" /> <PackageReference Include="HotChocolate.Data.Entityframework" Version="13.9.0" /> <PackageReference Include="Microsoft.EntityframeworkCore.Design" Version="8.0.2"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.EntityframeworkCore.SqlServer" Version="8.0.2" /> </ItemGroup> </Project>
docker-compose.yaml
version: '3' services: sqlserver: image: "mcr.microsoft.com/mssql/server:2017-latest" environment: ACCEPT_EULA: "Y" SA_PASSWORD: "pa55w0rd!" MSSQL_PID: "Express" ports: - "1433:1433"
appsettings.Development.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "ConnectionStrings": { "CommandConStr" : "Server=localhost,1433;Database=CommandsDB;User Id=sa;Password=pa55w0rd!" } }
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Startup.cs
using CommanderGQL.Data; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace CommanderGQL { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } //public IConfiguration Configuration { get; } private readonly IConfiguration Configuration; public void ConfigureServices(IServiceCollection services) { services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer (Configuration.GetConnectionString("CommandConStr"))); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // Configure production environment here } app.UseRouting(); app.UseEndpoints(endpoints => { // Configure endpoints here }); } } }
Platform.cs
using System.ComponentModel.DataAnnotations; namespace CommanderGQL.Models { public class Platform { [Key] public int Id { get; set; } public string Name { get; set; } public string LicenseKey { get; set; } } }
AppDbContext.cs
using CommanderGQL.Models; using Microsoft.EntityFrameworkCore; namespace CommanderGQL.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Platform> Platforms { get; set; } } }
Program.cs
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
问题根源是你的.NET 8项目使用了顶级语句模式的Program.cs,但传统的Startup.cs并没有被程序加载,导致EF Core在执行迁移命令时,无法找到AppDbContext的配置服务。
下面提供两种可行的修复方案,任选其一即可:
方案1:直接在Program.cs中配置DbContext
删除或保留Startup.cs均可,将DbContext的配置逻辑移到Program.cs中,更新后的代码如下:
using CommanderGQL.Data; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); // 配置AppDbContext服务 builder.Services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(builder.Configuration.GetConnectionString("CommandConStr"))); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
方案2:让Program.cs启用Startup类
如果你想保留Startup.cs的结构,修改Program.cs来加载并使用Startup类:
using CommanderGQL; var builder = WebApplication.CreateBuilder(args); // 初始化Startup并配置服务 var startup = new Startup(builder.Configuration); startup.ConfigureServices(builder.Services); var app = builder.Build(); // 使用Startup配置请求管道 startup.Configure(app, app.Environment); app.Run();
完成修改后,重新执行dotnet ef migrations add AddPlatformToDb命令即可正常生成迁移。
内容的提问来源于stack exchange,提问作者kamil

