ASP.NET 从配置文件中读取的数据库上下文的核心 运行 迁移 (appsettings.json)
ASP.NET Core run migration for a database context that reads from the configuration file (appsettings.json)
我正在玩 ASP.NET 核心 1.1 应用程序,我正在尝试从配置文件中读取连接字符串。
我的数据库上下文 class 如下所示:
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
string connString = "some hardcoded connection string";
builder.UseSqlServer(connString);
return new ApplicationDbContext(builder.Options);
}
}
运行 迁移工作正常(例如 dotnet ef database update
)。
如果我想删除硬编码的连接字符串,我将面临以下问题:
- 如果我尝试将
IConfiguration
注入 ApplicationDbContext
,迁移将失败并显示 No parameterless constructor defined for this object.
- 如果不注入一些东西,我无法找到从配置文件中读取信息的方法
我应该如何进行?
谢谢。
[编辑]
在 Startup.cs
中,我已经配置了连接字符串并且它工作正常(运行时):
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
//services.AddApplicationInsightsTelemetry(Configuration);
string connString = ConfigurationExtensions.GetConnectionString(Configuration, "DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connString));
services.AddMvc();
}
问题是 dotnet migrations
似乎需要数据库上下文中的无参数构造函数并实现 IDbContextFactory<>
,我不知道如何注入配置。
尝试使用 ApplicationDbContext 的 IOptions<> 后编辑
我已经尝试了建议的解决方案,但我无法使其工作,因为 dotnet migration
将调用默认构造函数。
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
private IOptions<DefaultConnectionValue> ConnOptions;
private string connectionString;
public ApplicationDbContext()
{
Console.WriteLine("Default constructor was called");
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IOptions<DefaultConnectionValue> connOptions) : base(options)
{
ConnOptions = connOptions;
connectionString = connOptions.Value.Value;
Console.WriteLine($"Injected connection string = {connectionString}");
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
//string connString = ConfigurationExtensions.GetConnectionString(null, "DefaultConnection");
builder.UseSqlServer(connectionString);
return new ApplicationDbContext(builder.Options, ConnOptions);
}
我遇到了同样的问题,我通过以下方式解决了它:
- 在服务集合中使用连接字符串注册选项
- 将选项注入 DBContext
- DBContext 无参数构造函数中的用户连接字符串
因此,您将拥有迁移所需的无参数构造函数。
注册配置设置的方法如下:
public class Startup
{
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Adds services required for using options.
services.AddOptions();
// Register the IConfiguration instance which MyOptions binds against.
services.Configure<MyOptions>(Configuration);
...
}
}
然后您可以将其用作休假(这是控制器示例,但您可以对 DBContext 执行相同的操作):
public class HomeController : Controller
{
private readonly MyOptions _optionsAccessor;
public HomeController(IOptions<MyOptions> optionsAccessor)
{
//injection of your configuration object with connection string
_optionsAccessor = optionsAccessor.Value;
}
public IActionResult Index()
{
var option1 = _optionsAccessor.Option1;
var option2 = _optionsAccessor.Option2;
return Content($"option1 = {option1}, option2 = {option2}");
}
}
有关配置设置用法的更多信息,请查看此处:Configuration。
更新:
您也可以尝试不同的方法 - 读取 DBContext 构造函数内部的配置:
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
private string connectionString;
public ApplicationDbContext()
{
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string
var configuration = builder.Build();
connectionString = ""; //FILL THE CONNECTION STRING FROM THE CONFIGURATION OBJECT
}
...
}
我正在玩 ASP.NET 核心 1.1 应用程序,我正在尝试从配置文件中读取连接字符串。
我的数据库上下文 class 如下所示:
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
string connString = "some hardcoded connection string";
builder.UseSqlServer(connString);
return new ApplicationDbContext(builder.Options);
}
}
运行 迁移工作正常(例如 dotnet ef database update
)。
如果我想删除硬编码的连接字符串,我将面临以下问题:
- 如果我尝试将
IConfiguration
注入ApplicationDbContext
,迁移将失败并显示No parameterless constructor defined for this object.
- 如果不注入一些东西,我无法找到从配置文件中读取信息的方法
我应该如何进行?
谢谢。
[编辑]
在 Startup.cs
中,我已经配置了连接字符串并且它工作正常(运行时):
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
//services.AddApplicationInsightsTelemetry(Configuration);
string connString = ConfigurationExtensions.GetConnectionString(Configuration, "DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connString));
services.AddMvc();
}
问题是 dotnet migrations
似乎需要数据库上下文中的无参数构造函数并实现 IDbContextFactory<>
,我不知道如何注入配置。
尝试使用 ApplicationDbContext 的 IOptions<> 后编辑
我已经尝试了建议的解决方案,但我无法使其工作,因为 dotnet migration
将调用默认构造函数。
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
private IOptions<DefaultConnectionValue> ConnOptions;
private string connectionString;
public ApplicationDbContext()
{
Console.WriteLine("Default constructor was called");
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IOptions<DefaultConnectionValue> connOptions) : base(options)
{
ConnOptions = connOptions;
connectionString = connOptions.Value.Value;
Console.WriteLine($"Injected connection string = {connectionString}");
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
//string connString = ConfigurationExtensions.GetConnectionString(null, "DefaultConnection");
builder.UseSqlServer(connectionString);
return new ApplicationDbContext(builder.Options, ConnOptions);
}
我遇到了同样的问题,我通过以下方式解决了它:
- 在服务集合中使用连接字符串注册选项
- 将选项注入 DBContext
- DBContext 无参数构造函数中的用户连接字符串
因此,您将拥有迁移所需的无参数构造函数。
注册配置设置的方法如下:
public class Startup
{
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Adds services required for using options.
services.AddOptions();
// Register the IConfiguration instance which MyOptions binds against.
services.Configure<MyOptions>(Configuration);
...
}
}
然后您可以将其用作休假(这是控制器示例,但您可以对 DBContext 执行相同的操作):
public class HomeController : Controller
{
private readonly MyOptions _optionsAccessor;
public HomeController(IOptions<MyOptions> optionsAccessor)
{
//injection of your configuration object with connection string
_optionsAccessor = optionsAccessor.Value;
}
public IActionResult Index()
{
var option1 = _optionsAccessor.Option1;
var option2 = _optionsAccessor.Option2;
return Content($"option1 = {option1}, option2 = {option2}");
}
}
有关配置设置用法的更多信息,请查看此处:Configuration。
更新:
您也可以尝试不同的方法 - 读取 DBContext 构造函数内部的配置:
public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext>
{
private string connectionString;
public ApplicationDbContext()
{
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string
var configuration = builder.Build();
connectionString = ""; //FILL THE CONNECTION STRING FROM THE CONFIGURATION OBJECT
}
...
}