Hoping for guidance on best practices for setting a connection string in a .NET 5 Web API. I am using EF Core Power Tools to reverse engineer a database model and I have a connection string in an appsettings.json file. Trying to figure out how I should apply the steps from Microsoft's DbContext configuration documentation with my existing setup.
Project setup (shortened for brevity) basically looks like this:
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "..."
}
}
Startup.cs
namespace API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
var builder = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false, true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
Globals.Configuration = Configuration;
}
}
}
ApplicationDbContext.cs (autogenerated by EF Core Power Tools)
namespace API.Data
{
public partial class ApplicationDbContext : DbContext
{
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
...
}
}
ExampleController.cs
namespace API.Controllers
{
[ApiController]
[Route("example")]
public class ExampleController : ControllerBase
{
[HttpGet("test")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<ApiResponse> GetExample()
{
using (var db = new ApplicationDbContext())
{
...
}
}
}
}
Now, that setup alone does not work (example controller would result in a "No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method..." error).
I have been working around this by adding a Connection String
property inside the ApplicationDbContext.cs
class (after it autogenerates) and setting the property within ConfigureServices inside Startup.cs
like this:
ApplicationDbContext.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
That does allow the use of using(var db = new ApplicationDbContext() { }
throughout the application, but this connection string setup gets overwritten every time I refresh the model with EF Core Power Tools.
Is there a better example to follow, or what's the best approach here? Thanks!
CodePudding user response:
First of All, as you have configured DB Connection as a option. so there is no need for default constructor of ApplicationDbContext
public partial class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
this should be fine, if you want to set connection string from startup
Now as you have already injecting ApplicationDbContext
in the startup, you can easily use on controller as a dependency injection rather than creating an new object. because creating new object you'll need to set connection string on that AppDbContext and which is not a good approach!
[ApiController]
[Route("example")]
public class ExampleController : ControllerBase
{
private readonly ApplicationDbContext _applicationDbContext;
ExampleController (private ApplicationDbContext applicationDbContext) {
_applicationDbContext = applicationDbContext;
}
[HttpGet("test")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<ApiResponse> GetExample()
{
//use db context
var something = _applicationDbContext;
}
}