Pietro
Pietro

Reputation: 781

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.

Upvotes: 6

Views: 6093

Answers (2)

Mohamed Elrashid
Mohamed Elrashid

Reputation: 8589

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.

Upvotes: 15

Sarvesh Mishra
Sarvesh Mishra

Reputation: 2072

If you are not creating object, then don't dispose it. Let IOC container handle it.

btw, I don't think this block of code is required. MCContext is a dependency, so its instance creation and injection gets done by IOC container.

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

Upvotes: 0

Related Questions