无法解析“Microsoft.EntityFrameworkCore.DbContextOptions”类型的服务
c#
我正在尝试在 ASP.NET Core 项目上使用 EF Core 5.0 访问数据库。对于第一次迁移,我覆盖OnConfiguring()了 DBContext 上的方法并成功更新了数据库。
对于第二次迁移,我决定按照指南在 ASP.NET Core 中使用依赖项注入。这是我所做的更改。
- 加入
services.AddDbContext我的Startup.cs。 OnConfiguring()从 中删除了该方法DBContext。
运行后dotnet ef migrations add Posts,我收到以下错误:
Microsoft.EntityFrameworkCore.Design.OperationException:
Unable to create an object of type 'BlogContext'.
For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
如果我添加 --verbose 标志,我会得到这个输出:
Build started...
dotnet build blog/app/app.csproj /verbosity:quiet /nologo
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.50
Build succeeded.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider in assembly 'app'...
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 'BlogContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'BlogContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
---> System.InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[app.Data.BlogContext]' while attempting to activate 'app.Data.BlogContext'.
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.<FindContextTypes>b__13()
Unable to create an object of type 'BlogContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
但是,当我运行 Web 应用程序时,代码按预期工作,因为在BlogContextDI 层创建并注入到我的类中,并且我可以访问数据库。
因此,我猜测 DI 层在运行dotnet ef migrations add命令时没有按预期运行。
这是我的代码。
// Program.cs
public class Program
{
public static void Main(string[] args)
{
IHostBuilder builder = Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
IHost host = builder.Build();
host.Run();
}
}
// BlogContext
using app.Models;
using Microsoft.EntityFrameworkCore;
namespace app.Data
{
public class BlogContext : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> Comments { get; set; }
public BlogContext(DbContextOptions<BlogContext> options) : base(options)
{
}
}
}
// Startup.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public string ConnectionString => Configuration.GetConnectionString("Blog");
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BlogContext>(opt => { opt.UseSqlite(ConnectionString); });
}
}
无论是Startup和BlogContext住在同一个项目。
回答
感谢 Ivan 和 Kirk 上面的评论并阅读了整个详细的输出,我找到了问题所在。原来我没有遵循Program.cs.
从文档中,
The tools first try to obtain the service provider by invoking Program.CreateHostBuilder(), calling Build(), then accessing the Services property.
我Program.cs通过移动CreateHostBuilder()inside重构了原始文件main(),这破坏了 ef-core 迁移。
修改Program.cs为以下后,它按预期工作。
public class Program
{
public static void Main(string[] args)
=> CreateHostBuilder(args).Build().Run();
// EF Core uses this method at design time to access the DbContext
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(
webBuilder => webBuilder.UseStartup<Startup>());
}
THE END
二维码