Entity Framework Core 1.0 DbContext not scoped to http request

我只是一个虾纸丫 提交于 2019-12-09 06:44:35

问题


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

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.

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

and this middleware is immediately before than MVC6 in the pipeline

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

The DbContext instance in my Middleware is not the same as the instance being injected during the MVC lifetime.

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

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..


回答1:


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.

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.

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



来源:https://stackoverflow.com/questions/35329480/entity-framework-core-1-0-dbcontext-not-scoped-to-http-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!