Asp.net core mvc 实体框架核心1.0 DbContext的作用域未限定为http请求

Asp.net core mvc 实体框架核心1.0 DbContext的作用域未限定为http请求,asp.net-core-mvc,dbcontext,middleware,entity-framework-core,asp.net-core-1.0,Asp.net Core Mvc,Dbcontext,Middleware,Entity Framework Core,Asp.net Core 1.0,我和罗文·米勒一起看了这段视频就明白了 (第22分钟) 在Startup.cs中将Entity Framework Core(以前称为EF7)配置为ASP.NET Core 1.0应用程序(以前称为ASP.NET 5)的方法如下: public void ConfigureServices(IServiceCollection services) { //Entity Framework 7 scoped per request?? service

我和罗文·米勒一起看了这段视频就明白了 (第22分钟)
Startup.cs
中将Entity Framework Core(以前称为EF7)配置为ASP.NET Core 1.0应用程序(以前称为ASP.NET 5)的方法如下:

    public void ConfigureServices(IServiceCollection services)
    {
        //Entity Framework 7 scoped per request??
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyDbContext>(options =>
            {
                options
                  .UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]);
            });

        //MVC 6
        services.AddMvc();
    }
public void配置服务(IServiceCollection服务)
{
//实体框架7每个请求的作用域??
services.AddEntityFramework()
.AddSqlServer()文件
.AddDbContext(选项=>
{
选择权
.UseSqlServer(配置[“数据:默认连接:连接字符串]);
});
//MVC6
services.AddMvc();
}
这个DbContext的作用域将限定为一个http请求,这样无论何时在整个http管道(包括中间件或MVC)的代码中使用DbContext,我们都可以确定DI容器注入的实例是相同的

但问题是,它似乎不是这样工作的。在MVC的生命周期内,注入的DbContext实例是相同的,但如下所述: 我正在尝试将以下中间件插入管道,以在控制器完成执行后实现某种集中提交/回滚:

public class UnitOfWorkMiddleware
{
    private readonly RequestDelegate _next;
    private readonly MyDbContext _dbContext;
    private readonly ILogger _logger;

    public UnitOfWorkMiddleware(RequestDelegate next, MyDbContext dbContext, ILoggerFactory loggerFactory)
    {
        _next = next;
        _dbContext = dbContext;
        _logger = loggerFactory.CreateLogger<UnitOfWorkMiddleware>();
    }

    public async Task Invoke(HttpContext httpContext)
    {
        await _next.Invoke(httpContext);
        _logger.LogInformation("Saving changes for unit of work if everything went good");
        await _dbContext.SaveChangesAsync();
    }
}
公共类UnitOfWork中间件
{
private readonly RequestDelegate\u next;
私有只读mydbcontextu dbContext;
专用只读ILogger\u记录器;
公共UnitOfWorkMiddleware(RequestDelegate-next、MyDbContext-dbContext、ILoggerFactory-loggerFactory)
{
_下一个=下一个;
_dbContext=dbContext;
_logger=loggerFactory.CreateLogger();
}
公共异步任务调用(HttpContext HttpContext)
{
wait_next.Invoke(httpContext);
_logger.LogInformation(“如果一切顺利,则保存工作单元的更改”);
wait_dbContext.saveChangesSync();
}
}
这个中间件比管道中的MVC6更早

//inside Configure(IApplicationBuilder app) in Startup.cs
app.UseMiddleware<UnitOfWorkMiddleware>();
app.UseMvcWithDefaultRoute();
//在Startup.cs中进行内部配置(IAApplicationBuilder应用程序)
app.UseMiddleware();
app.UseMvcWithDefaultRoute();
我的中间件中的DbContext实例与MVC生命周期中注入的实例不同

这是预期的吗?DbContext的作用域不应该是http请求吗?有可能实现我想要实现的目标吗


计划B将使用一个MVC6全局过滤器(如果我能找到一些关于如何做到这一点的文档)。我假设作为MVC 6框架的一部分,注入的DbContext实例将是相同的。

经过更多测试,我可以确认DbContext仅在MVC执行的生命周期内作用于http请求(可能是MVC负责处理DbContext),因此,管道中之前或之后的任何中间件都不会注入相同的DbContext实例

然后我决定在MVC6中添加一个全局过滤器(因为过滤器是MVC框架的一部分),这样我就可以在操作执行前后访问同一个DbContext实例

如果有人对如何创建此全局筛选器检查感兴趣:

不过,我认为您严重误用了DbContext。这些东西应该尽可能晚地创建,并尽快销毁。DbContext由作用域为http请求的DI容器实例化。我仍然依赖它来创建和销毁DbContext实例。如果我让我的存储库保存DbContext更改,在MVC将响应传递到管道中的下一项之前,这个DbContext实例仍然不会被销毁(因为如果我没有弄错的话,默认情况下DI容器会以这种方式管理它)。我的方法有什么不同?是的,DbContext将在稍早一点被实例化,但同时被销毁,就像我没有使用过滤器一样,你不认为吗?另外,我不知道还有什么其他方法可以像事务一样处理http请求,而不需要在控制器执行后有一个集中的位置来确保一切正常。在控制器中注入DbContext是个坏主意,但在集中式过滤器中似乎是更好的方法。对于类似事务的方法有什么建议吗?