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

时间:2019-01-18 10:46:33

标签: c# asp.net-core entity-framework-core

在阅读了大量有关该主题的内容之后,似乎一个好方法是为每个请求创建一个上下文。

要达到这个目的,我在Startup.cs中声明了两个静态对象

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

然后在应用程序启动时使用init optionsBuilder(因此仅一次):

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

在每次请求时db:

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

然后,当我需要控制器或剃须刀页面cs中的上下文时,可以使用Startup.db来获取它:

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

我不按照here丢弃上下文

由于我对DI不熟悉,所以我想知道这种方法是否正确,或者是否缺少任何内容。

2 个答案:

答案 0 :(得分:4)

基于What is new in EF Core 2.0 - EF Core | Microsoft Docs

如果您希望每个请求一次新的上下文:AddDbContext

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

那么您可以

public class TiketsController : ControllerBase
{
    private readonly MCContext _context;

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

在ASP.NET Core应用程序中使用EF Core的基本模式   通常涉及将自定义DbContext类型注册到   依赖项注入系统,以后再获取该类型的实例   通过控制器中的构造函数参数。这意味着一个新的   为每个请求创建DbContext实例。

,但是如果您需要高性能/安全重用:AddDbContextPool

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

那么您可以

public class TiketsController : ControllerBase
{
    private readonly MCContext _context;

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

如果使用此方法,则在请求DbContext实例时   通过控制器,我们将首先检查是否有可用实例   在游泳池。请求处理完成后,   实例被重置,并且实例本身返回到池中。

答案 1 :(得分:0)

如果您不创建对象,请不要处置它。让IOC容器处理它。

顺便说一句,我认为不需要这段代码。 MCContext是一个依赖项,因此它的实例创建和注入由IOC容器完成。

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