c# - 错误:System.InvalidOperationException:没有为此 DbContext 配置数据库提供程序
问题描述
开始
我一直在尝试启动一个小项目,以便我可以学习 EF 并使用 C# 创建 API。我正在关注API 的本教程并遵循EF 设置的本教程。最初,我在创建初始迁移时遇到了问题。这导致我发现有关创建 DbContextFactory 的信息。那行得通,我能够创建并运行我的初始迁移。但是,现在,每当我尝试调用我的 API 路由时,我都会收到此错误:
System.InvalidOperationException:没有为此 DbContext 配置数据库提供程序。可以通过覆盖“DbContext.OnConfiguring”方法或在应用程序服务提供程序上使用“AddDbContext”来配置提供程序。如果使用了“AddDbContext”,那么还要确保您的 DbContext 类型在其构造函数中接受 DbContextOptions 对象并将其传递给 DbContext 的基本构造函数。在 Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider,IDbContextOptions contextOptions,DbContext 上下文)
在 Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() 在 Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() 在 Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies.get_EntityFinderFactory() 在 Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_Finder() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet
1.FindAsync(Object[] keyValues) at Games.Controllers.GameController.Get(Int32 id) in K:\Projects\c#\Games\Games\Controllers\GameController.cs:line 23 at lambda_method5(Closure, Object) at Microsoft .AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,Object[] 参数)在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask`1 actionResultValueTask)在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序,Task lastTask,State next,Scope 范围,Object state,Boolean isCompleted)在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker。Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() 的 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 的 Rethrow(ActionExecutedContextSealed context) --- 堆栈结束从先前位置跟踪 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker 的 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker .g__Awaited|17_0(ResourceInvoker 调用程序,任务任务,IDisposable 范围)在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点,任务 requestTask,ILogger 记录器)在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware。Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
在我开始编写代码之前,我的项目已设置好,以便我在同一个解决方案中拥有 API 项目和数据库项目。API 项目是启动项目,依赖于数据库项目。我也在使用 EF Core 5.0 和 .NET 5。
编码
GameDbContext.cs
using Games.Db.Tables;
using Microsoft.EntityFrameworkCore;
namespace Games.Db
{
public class GameDbContext : DbContext
{
public GameDbContext(DbContextOptions<GameDbContext> options) : base(options)
{
}
public DbSet<Game> Game { get; set; }
public DbSet<Platform> Platform { get; set; }
public DbSet<Medium> Medium { get; set; }
}
}
GameDbContextFactory.cs
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
namespace Games.Db
{
public class GameDbContextFactory : IDesignTimeDbContextFactory<GameDbContext>
{
public GameDbContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("migrations.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<GameDbContext>();
var connectionString = configuration.GetConnectionString("MigrationsHelperConnection");
optionsBuilder.UseSqlServer(connectionString);
return new GameDbContext(optionsBuilder.Options);
}
}
}
启动.cs
using Games.Db;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace Games
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<GameDbContext>();
services.AddTransient<DbContext, GameDbContext>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Games", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Games v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
我尝试了什么
我发现了这个问题,并将其添加OnConfiguring()
到我的 GameDbContext 中,并创建了这个:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var directory = Directory.GetCurrentDirectory();
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("migrations.json")
.Build();
var connectionString = configuration.GetConnectionString("MigrationsHelperConnection");
optionsBuilder.UseSqlServer(connectionString);
}
但是,此时我得到的错误是它找不到migrations.json
. 这是因为它正在查找我的 API 项目的目录,并且该文件位于我的数据库项目中。
问题
我显然在这一切中遗漏了一些非常微妙的东西。可能是将近凌晨 2 点,咖啡在几个小时前就用完了。但我完全被难住了。我会错过什么?
编辑
这是解决方案布局的图片:
解决方案
在 Alexander 的一些提示和指导下,我更新了我的函数以更改Directory
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var configuration = new ConfigurationBuilder()
.SetBasePath(directory)
.AddJsonFile("migrations.json")
.Build();
var connectionString = configuration.GetConnectionString("MigrationsHelperConnection");
optionsBuilder.UseSqlServer(connectionString);
}
推荐阅读
- reactjs - 运行`npm run build`时Reactjs缺少文件
- css - css 在使用 scss 的反应应用程序中不起作用
- javascript - 反应原生垂直平面列表不向下滚动
- python - 在一维布尔数组中查找连续区域
- python - python pygame窗口不会关闭“没有响应”
- javascript - 使用 Javascript、DOM 和 replaceChild() 方法创建装箱单
- snakemake - 没有歧义时的 AmbiguousRuleException
- python - 有选择地删除熊猫数据框 NaN 行,按包含重复项的 id 列分组
- flutter - VS Code Wrap with Widget Auto Suggestion 建议参数/参数
- python - Matplotlib 获取 z 数据