I am building up an ASP.Net Core API and I have not been able to find a way to get the connection string from the DBContextOptions.
I have the DBContext in my startup.cs as shown below;
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();
});
}
And in my Context class, I have the following constructor;
public MainContext(DbContextOptions<MainContext> options) : base(options)
{
}
but it doesn't work unless I add an actual connection string in the DBContext class, OnConfiguring method, as shown below;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//TODO Move connection string to a secure location
optionsBuilder.UseSqlServer(@"Server= .....");
}
I can see that the Startup.cs is getting the correct connection string from the appsettings.json file when I debug and examine the value in Configuration.GetConnectionString("MainConnection").
I would think that passing the options into the DbContext class via DI would have passed the connection string but the DbContect class doesn't work unless I have that optionBuilder.UseSqlServer() in the OnConfiguring method.
I found this SO post https://stackoverflow.com/questions/33532599/asp-net-5-multiple-dbcontext-problems, that talks about using the following code to extract the connection string from the options property
public ResourceDbContext(DbContextOptions options) : base(options)
{
_connectionString = ((SqlServerOptionsExtension)options.Extensions.First()).ConnectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(_connectionString);
}
But when I try to use it, I find that there is no longer a First() method in options.Extensions
So, my first question is...
Why doesn't the DBContext class work without having to add the connection string in the OnConfiguring method
My second question is ...
If the connection string is required in the OnCOnfiguring method, how can I get it from the DbContextOptions options object rather than having to explicitly provide it in the OnConfiguring method --> optionsBuilder.UseSqlServer(@"Server= .....");
At least for EF Core 1.1, you need to use 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;
}
}
}
}
The null check is there in case you're using opt.UseInMemoryDatabase()
in your Startup.cs