Hello,
we are currently evaluating the usability of Entity Framework Core Code First in a Blazor Server application.
We try to migrate from a Database First approach where we created a DbContext
instance (by a IDbContextFactory
) per database operation.
Example:
public class ReleaseService
{
...
public Release LoadRelease(int userId, int releaseId)
{
using (var context = _contextFactory.CreateDbContext())
{
return context.Database.SqlQuery<Release>(
@$"rel.SelRelease
@person_id={userId},
@release_id={releaseId}
")
.AsEnumerable()
.FirstOrDefault();
}
}
}
Our Blazor Server application currently uses cascading parameters where the MainLayout.razor
cascades down certain class objects to child pages / components.
The most central entity is a User
(entity). Therefore, we load it once in MainLayout.OnInitialized
and cascade (pass) it down to child components.
Now, let’s consider following succession in our application:
- load
User
entity in MainLayout.OnInitialized
- navigate to any application page
- in an edit page load another entity, let’s say a
Request
entity
- edit some properties of the
Request
entity and save it; also set Request.UpdatedByUser
during save
Question
Which approach would be better?
a) long-living DbContext (lifetime: Scoped)
We create the DbContext
in MainLayout.OnInitialized
, do NOT close it here but cascade (pass) it down to every child component.
Once the user navigates to the edit page, we reuse the DbContext
, manipulate Request
entity and save the changes to database.
Consequence: The DbContext
instance will live for the whole browser session of the current user.
b) DbContext per operation
After loading the User
entity in MainLayout.OnInitialized
we directly close the DbContext
.
Once the user navigates to the edit page, we create a new DbContext
instance for our edit operation.
In this new DbContext
instance we reload the User
entity for having it in EF Core tracker.
We manipulate the Request
entity by the edit page. On “Save” click we also set Request.UpdatedByUser
and then save all changes to database.
Consequence: The secondly created DbContext
instance will be closed only when the user navigates away from the edit page, more precisely: once the edit component with the “Save” functionality is destroyed.