首页 > 解决方案 > 在 ASP.Net Core 中为每个请求创建一次 EF Core 上下文

问题描述

在阅读了很多关于该主题的内容之后,看起来一个好的方法是为每个请求创建一次上下文。

为了实现这一点,在 Startup.cs 我声明了两个静态对象

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

然后在应用程序启动时初始化 optionsBuilder(所以只有一次):

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

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

我不按照这里处理上下文

由于我不熟悉 DI,我想知道这种方法是否正确,或者我是否遗漏了什么。

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

解决方案


基于EF Core 2.0 中的新增功能 - EF Core | 微软文档

如果您想要每个请求一次新的上下文: 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 实例时,我们将首先检查池中是否有可用的实例。一旦请求处理完成,实例上的任何状态都会被重置,并且实例本身会返回到池中。


推荐阅读