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= …..");
Best Answer
At least for EF Core 1.1, you need to use
FindExtension<SqlServerOptionsExtension>()
The null check is there in case you're using
opt.UseInMemoryDatabase()
in yourStartup.cs