简体   繁体   中英

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.

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.

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(); 
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM