实体框架核心1.0 DbContext不限于http请求 [英] Entity Framework Core 1.0 DbContext not scoped to http request

查看:98
本文介绍了实体框架核心1.0 DbContext不限于http请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过与罗文·米勒一起观看此视频,我了解了 https://channel9.msdn.com/Series/Whats- ASPNET-5/06的新功能 (第22分钟)Startup.cs中将Entity Framework Core(以前称为EF7)配置为ASP.NET Core 1.0应用(以前称为ASP.NET 5)的方式如下:

I understood by watching this video with Rowan Miller https://channel9.msdn.com/Series/Whats-New-with-ASPNET-5/06 (at minute 22) that the way of configuring Entity Framework Core (previously known as EF7) into an ASP.NET Core 1.0 app (previously known as ASP.NET 5) in Startup.cs is as follows:

    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容器上的相同.

and that this DbContext will be scoped to an http request so that whenever in the code throughout the http pipeline (including middleware or MVC) a DbContext is used, we know for sure that the instance injected by the DI container will be the same.

但是问题在于它似乎无法以这种方式工作.在MVC的生命周期内,确实注入的DbContext实例是相同的,但如下所述:

But the problem is that it does not seem to work that way. Within the lifetime of MVC it is true that the DbContext instance injected is the same, but as described here: Entity Framework Core 1.0 unit of work with Asp.Net Core middleware or Mvc filter I am trying to plug into the pipeline the following middleware to achieve some kind of centralised Commit/Rollback after a controller finalises execution:

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早得多

and this middleware is immediately before than MVC6 in the pipeline

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

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

这是预期的吗?不应将DbContext限制为http请求吗?可以实现我试图实现的目标吗?

Is this expected? Shouldn't a DbContext be scoped to an http request? Is possible to achieve what I was trying to achieve?

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

The plan B would be to use an MVC 6 Global filter (if I can find some documentation on how to do this). I assume that being part of MVC 6 framework, the DbContext instance injected will be the same..

推荐答案

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

After more testing I can confirm that the DbContext is scoped to the http request only during the lifetime of the MVC execution (maybe MVC is in charge of disposing of the DbContext), so any middleware before or after in the pipeline won't have the same instance of DbContext injected.

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

I decided then to add a global filter to MVC 6 (because filters are part of MVC framework) so that I can access the same DbContext instance before and after the action's execution.

如果有人对如何创建此全局过滤器感兴趣,请检查: 带有Asp.Net Core中间件或Mvc过滤器的Entity Framework Core 1.0工作单元

If anybody is interested on how to create this global filter check: Entity Framework Core 1.0 unit of work with Asp.Net Core middleware or Mvc filter

这篇关于实体框架核心1.0 DbContext不限于http请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆