【发布时间】:2020-06-16 16:51:47
【问题描述】:
我有 ASP.Net Core 2.1 和 EF Core 2.1。这就是我的 DbContext 类的样子
app.DAL.EF -> 层
using app.domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
namespace app.EF
{
public class MyAppContext : DbContext
{
public MyAppContext(DbContextOptions<MyAppContext> options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new CustomerConfiguration());
modelBuilder.HasDefaultSchema("app");
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
public DbSet<Customer> Customers { get; set; }
}
public class MyAppContextConfiguration : IDesignTimeDbContextFactory<MyAppContext>
{
public MyAppContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT ") ?? "Production" }.json", optional: true)
.Build();
var optionsBuilder = new DbContextOptionsBuilder<MyAppContext>();
//optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
var dbConString = configuration.GetConnectionString("ITMDbConnection");
optionsBuilder.UseSqlServer(dbConString);
return new MyAppContext(optionsBuilder.Options);
}
}
public class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.HasKey(x => x.Id);
}
}}
app.DI -> 层
public static class Factory
{
public static void Initialize(ref IServiceCollection services)
{
//services.AddTransient<MyAppContext>();
services.AddDbContext<MyAppContext>(options =>
{
});
//services.AddTransient<MyAppContextConfiguration>();
services.AddTransient<ICustomerRepository, CustomerRepository>();
}
}
app.API -> 层
namespace app.api
{
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)
{
Factory.Initialize(ref services);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}}
从包管理器控制台运行Add-Migration DbInit时,抛出以下错误
没有为此 DbContext 配置数据库提供程序。可以通过覆盖 DbContext.OnConfiguring 方法或在应用程序服务提供者上使用 AddDbContext 来配置提供者。如果使用了 AddDbContext,那么还要确保您的 DbContext 类型在其构造函数中接受 DbContextOptions 对象并将其传递给 DbContext 的基本构造函数。
谢谢!
【问题讨论】:
-
错误信息很清楚。这应该使用什么数据库?甲骨文、PostgreSQL、MySQL?它将连接到哪里?一个本地数据库,一个远程数据库,AWS RDS?您需要在
AddDbContext中指定提供者和连接。其中,顺便说一句,应该在Startup.cs。这些方法是 DI 配置方法,而不是工厂或层。如果你想简化你的代码,你可以创建一个扩展方法来接收并且返回一个IServiceCollection,允许你像其他DI配置方法一样链接配置调用 -
@PanagiotisKanavos
MyAppContextConfiguration类中提到的不一样吗? -
您没有在任何地方使用
CreateDbContext。这段代码有点过于复杂。那些类、方法不是层,它们只是一个 DbContext 和一些启动配置方法。 DbContext 配置和 DI 注册由AddDbContext执行。一个简单的options.UseSqlServer(Configuration.GetConnectionString("ITMDbConnection"))就可以了。MyAppContextConfiguration类不在 Startup.cs 中的任何地方使用 -
ASP.NET Core 2.x 和 3.x 中的主机构建器已经执行了
CreateDbContext中的配置步骤 - 加载appsettings.json、任何环境文件等。这意味着ConfigurationStartup.cs中的字段可以加载连接字符串 -
如果我在 Factory 或 Startup 类中使用此
options.UseSqlServer()。然后引入了紧耦合
标签: c# entity-framework-core entity-framework-migrations asp.net-core-2.1 ef-core-2.1