简体   繁体   English

在ASP.Net Core中每个请求一次创建EF Core上下文

[英]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 为此,我在Startup.cs中声明了两个静态对象

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): 然后在应用启动时使用init optionsBuilder初始化(因此只有一次):

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

while db at each request: 而db每次请求时:

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: 然后,当我需要控制器或剃须刀页面cs中的上下文时,可以使用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. 因为我不熟悉DI,所以我想知道这种方法是否正确,或者是否缺少任何东西。

base on What is new in EF Core 2.0 - EF Core | 基于EF Core 2.0的新增功能-EF Core | Microsoft Docs 微软文档

If you want a new context once per request : AddDbContext 如果您希望每个请求一次新的上下文: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. 在ASP.NET Core应用程序中使用EF Core的基本模式通常包括将自定义DbContext类型注册到依赖项注入系统中,然后通过控制器中的构造函数参数获取该类型的实例。 This means a new instance of the DbContext is created for each requests. 这意味着将为每个请求创建一个新的DbContext实例。

but if you need High Performance/Safe reuse : AddDbContextPool 但是如果您需要高性能/安全重用: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. 如果使用此方法,则在控制器请求DbContext实例时,我们将首先检查池中是否有可用的实例。 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. 让IOC容器处理它。

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. MCContext是一个依赖项,因此它的实例创建和注入由IOC容器完成。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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