Daily Knowledge Drop
When configuring an Entity Framework DbContext
with the dependency injection container, it is possible to make use of the container to create an instance of the context on startup, to either create the database or apply database migrations.
Configuration
The AddDbContext
extension method is used to configure the Entity Framework DbContext on startup, registering the context with the dependency injection container:
var builder = WebApplication.CreateBuilder(args);
// configure the context and add to the DI Container
builder.Services.AddDbContext<DemoContext>(options =>
options.UseSqlServer(@"Server=.\SQLEXPRESS;Database=EFStartup;
Integrated Security=True;TrustServerCertificate=True"));
var app = builder.Build();
app.MapGet("/blogs", (DemoContext context) =>
{
return context.Blogs.ToList();
});
app.Run();
When the /blogs
endpoint is called and a DemoContext
is instantiated, the above will work provided that the database and relevent tables have already been created
- if not, and exception will be thrown, as the database is not automatically created.
Next we'll have a look at how to ensure the database is created on startup, using the services registered with the dependency injection container.
Startup
The process of ensuring the database is created, is relatively straightforward - Entity Framework does most of the heavy lifting for us:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<DemoContext>(options =>
options.UseSqlServer(@"Server=.\SQLEXPRESS;Database=EFStartup;
Integrated Security=True;TrustServerCertificate=True"));
var app = builder.Build();
// this block ensures the database is created
#if DEBUG
using (var scope = app.Services.CreateScope())
{
var startupContext = scope.ServiceProvider
.GetRequiredService<DemoContext>();
startupContext.Database.EnsureCreated();
}
#endif
app.MapGet("/blogs", (DemoContext context) =>
{
return context.Blogs.ToList();
});
app.Run();
Some notes on the above code:
- the
#if conditional
is used to ensure the code is only executed when debugging. It is NOT recommended to automatically create the database or apply migrations in non-development environments. The recommended approach is to use a CI/CD pipeline. - a new dependency injection scope is created (as the application host is technically not running yet) and a
DbContext
instance instantiated - the EnsureCreated method is called to create the database with the configured schema. This bypasses migrations - if the migrations are required to be run, then
startupContext.Database.Migrate()
should be called instead ofstartupContext.Database.EnsureCreated()
- the EnsureCreated is designed to be used when doing
testing or prototyping
where the database is dropped and recreated with each execution
Notes
A useful and time-saving way to use the already configured dependency injection container to instantiate the database context, and have EF do the heavy lifting to create the database with the correct schema.
References
Dependency Injection of an Entity Framework Context within Program.cs Using Top Level Statements
Daily Drop 230: 09-01-2023
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.On This Page