我正在构建一个ASP.Net Core API,但我无法找到从DBContextOptions获取连接字符串的方法。
我的startup.cs中有DBContext,如下所示;
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFrameworkSqlServer()
.AddDbContext<MainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MainConnection")));
services.AddMvc()
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
}
在我的Context类中,我有以下构造函数;
public MainContext(DbContextOptions<MainContext> options) : base(options)
{
}
但除非我在DBContext类OnConfiguring方法中添加实际的连接字符串,否则它不起作用,如下所示;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//TODO Move connection string to a secure location
optionsBuilder.UseSqlServer(@"Server= .....");
}
我可以看到,当我调试并检查Configuration.GetConnectionString(&#34; MainConnection&#34;)中的值时,Startup.cs从appsettings.json文件中获取正确的连接字符串。
我认为通过DI将选项传递到DbContext类会传递连接字符串,但DbContect类不起作用,除非我在OnConfiguring方法中有optionBuilder.UseSqlServer()。
我找到了这个SO帖子https://stackoverflow.com/questions/33532599/asp-net-5-multiple-dbcontext-problems,它讨论了如何使用以下代码从options属性中提取连接字符串
public ResourceDbContext(DbContextOptions options) : base(options)
{
_connectionString = ((SqlServerOptionsExtension)options.Extensions.First()).ConnectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(_connectionString);
}
但是当我尝试使用它时,我发现options.Extensions中不再有First()方法
所以,我的第一个问题是......
为什么DBContext类无需在OnConfiguring方法中添加连接字符串
我的第二个问题是......
如果OnCOnfiguring方法中需要连接字符串,我如何从DbContextOptions选项对象中获取它,而不必在OnConfiguring方法中显式提供它 - &gt; optionsBuilder.UseSqlServer(@&#34; Server = .....&#34;);
答案 0 :(得分:3)
在appsettings.json
内,您将创建以下内容:
{
"Database" : {
"ConnectionString" : "..."
}
}
然后在ConfigureServices
内,您将执行以下操作:
services.AddSingleton(_ => Configuration);
这基本上会填充IConfigurationRoot
属性。您可以在任何地方注入,并通过执行以下操作访问连接字符串:
private readonly IConfigurationRoot configuration;
private IDbConnection dbConnection { get; }
public Example(IConfigurationRoot configuration)
{
this.Configuration = configuration;
dbConnection = new SqlConnection(this.configuration.GetConnectionString("..."));
}
我的结构有点奇怪,你真的会简单地将ConnectionString
传递给另一个类,或者注入方法,但这会为你演示。但我相信Entity Framework 7有一个工厂直接接受连接字符串。希望这可以帮助你。
在实体框架中,ConfigureServices
:
services.AddSingleton<dbContext>(_ => new dbContext(Configuration.GetConnectionString("...")));
public class dbContext : DbContext
{
public dbContext(string dbConnection) : base(dbConnection)
{
}
}
一些额外的documentation。
答案 1 :(得分:1)
至少对于EF Core 1.1,您需要使用FindExtension<SqlServerOptionsExtension>()
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
namespace MyNamespace
{
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
var sqlServerOptionsExtension =
options.FindExtension<SqlServerOptionsExtension>();
if(sqlServerOptionsExtension != null)
{
string connectionString = sqlServerOptionsExtension.ConnectionString;
}
}
}
}
如果您在opt.UseInMemoryDatabase()
Startup.cs
,则会进行空检查
答案 2 :(得分:0)
对于EntityFrameworkCore 2.1.4
,您的连接字符串应类似于appsettings.json
"ConnectionStrings": {
"Connection1": "....",
"Connection2": "..."
},
将以下行添加到ConfigureServices
中的Startup.cs
方法中
services.AddSingleton(provider => Configuration);
在这些行之后,
services.AddDbContext<MyContextContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("Connection1")));
services.AddScoped<DbContext, MyContext>();
您的数据库上下文类应进行如下修改。
public partial class MyContext : DbContext
{
private readonly IConfiguration _configuration;
private IDbConnection DbConnection { get; }
public MyContext(DbContextOptions<MyContext> options, IConfiguration configuration)
: base(options)
{
this._configuration = configuration;
DbConnection = new SqlConnection(this._configuration.GetConnectionString("Connection1"));
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(DbConnection.ToString());
}
}
}