Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create EF Core Context once per request in ASP.Net Core

After reading a lot on the subject it looks like a good approach is to create a context once per request.

To achive this, in in Startup.cs I have declared two statics objects

public class Startup
{
    public static DbContextOptionsBuilder<MCContext> optionsBuilder = new DbContextOptionsBuilder<MCContext>();
    public static MCContext db = null;

then init optionsBuilder when the app starts (so only once):

public Startup(IConfiguration configuration)
{
    optionsBuilder.UseSqlServer(configuration["ConnectionStrings:DefaultConnection"]);
}

while db at each request:

app.Use(async (context, next) =>
{
    db = db ?? new MCContext(optionsBuilder.Options);
    await next.Invoke(); 
});

Then when I need the context in a controller or in a razor page cs I can get it using Startup.db:

User cur = await Startup.db.User.Where(x => x.Id == uid).FirstOrDefaultAsync();

I do not Dispose the Context as per here

As I'm not familiar with DI I wonder if this approach is correct or if I am missing anything.

like image 968
Pietro Avatar asked Dec 14 '22 13:12

Pietro


1 Answers

base on What is new in EF Core 2.0 - EF Core | Microsoft Docs

If you want a new context once per request : AddDbContext

public void ConfigureServices(IServiceCollection services)
{
 services.AddDbContext<MCContext >(
     options => options.UseSqlServer(connectionString));
 }

then you can

public class TiketsController : ControllerBase
{
    private readonly MCContext _context;

    public TiketsController (MCContext context)
    {
        _context = context;
    }
 }

The basic pattern for using EF Core in an ASP.NET Core application usually involves registering a custom DbContext type into the dependency injection system and later obtaining instances of that type through constructor parameters in controllers. This means a new instance of the DbContext is created for each requests.

but if you need High Performance/Safe reuse : AddDbContextPool

public void ConfigureServices(IServiceCollection services)
{
 services.AddDbContextPool<MCContext >(
     options => options.UseSqlServer(connectionString));
 }

then you can

public class TiketsController : ControllerBase
{
    private readonly MCContext _context;

    public TiketsController (MCContext context)
    {
        _context = context;
    }
 }

If this method is used, at the time a DbContext instance is requested by a controller we will first check if there is an instance available in the pool. Once the request processing finalizes, any state on the instance is reset and the instance is itself returned to the pool.

like image 133
Mohamed Elrashid Avatar answered Jan 02 '23 17:01

Mohamed Elrashid