实体框架核心1.0 DbContext没有作用于http请求

时间:2016-02-11 01:57:39

标签: asp.net-core-mvc dbcontext middleware entity-framework-core asp.net-core-1.0

通过观看Rowan Miller的视频,我明白了 https://channel9.msdn.com/Series/Whats-New-with-ASPNET-5/06 (第22分钟) 将实体框架核心(以前称为EF7)配置到Startup.cs中的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();
    }

并且这个DbContext将限定为一个http请求,这样无论何时在整个http管道(包括中间件或MVC)的代码中使用DbContext,我们都确定注入的实例通过DI容器将是相同的。

但问题是它似乎没有那样工作。在MVC的生命周期内,注入的DbContext实例是相同的,但如下所述:Entity Framework Core 1.0 unit of work with Asp.Net Core middleware or Mvc filter 我试图在控制器完成执行后,将以下中间件插入管道以实现某种集中式提交/回滚:

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

并且此中间件紧接在管道中的MVC6之前

//inside Configure(IApplicationBuilder app) in Startup.cs
app.UseMiddleware<UnitOfWorkMiddleware>();
app.UseMvcWithDefaultRoute();

我的中间件中的DbContext实例与MVC生命周期中注入的实例不同

这是预期的吗?不应该将DbContext范围限定为http请求吗?有可能实现我想要实现的目标吗?

计划B将使用 MVC 6全局过滤器(如果我可以找到有关如何执行此操作的文档)。我假设作为MVC 6框架的一部分,注入的DbContext实例将是相同的..

1 个答案:

答案 0 :(得分:4)

经过更多测试后,我可以确认DbContext的范围仅限于http请求在MVC执行的生命周期内(也许MVC负责处理DbContext),所以之前的任何中间件或者在管道中之后将没有注入相同的DbContext实例。

然后我决定将全局过滤器添加到MVC 6(因为过滤器是MVC框架的一部分),这样我就可以在执行动作之前和之后访问相同的DbContext实例。

如果有人对如何创建此全局过滤器检查感兴趣: Entity Framework Core 1.0 unit of work with Asp.Net Core middleware or Mvc filter