2

я понял, наблюдая это видео с Роуэн Миллер https://channel9.msdn.com/Series/Whats-New-with-ASPNET-5/06 (в минуту 22) , что способ конфигурирования Entity Framework ядра (ранее известный как EF7) в ASP .NET 1.0 ядро ​​приложения (ранее известное как ASP.NET 5) в Startup.cs выглядит следующим образом:Entity Framework Основные 1.0 DbContext не распространяется до запроса HTTP

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 Я пытаюсь подключить к конвейеру следующее промежуточное программное обеспечение для достижения какого-то централизованного Commit/Rollback после того, как контроллер завершит выполнение:

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 в моем Middleware не то же самое, как, например впрыскивается во время жизни MVC.

Ожидается ли это? Разве DbContext не должен быть привязан к HTTP-запросу? Можно ли достичь того, чего я пытался достичь?

План B должен был бы использовать глобальный фильтр MVC 6 (если я могу найти документацию о том, как это сделать). Я полагаю, что, будучи частью MVC 6 рамок, экземпляр DbContext закачиваемой будет такой же ..

ответ

3

После более тестирования я могу подтвердить, что 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

+0

Я думаю, вы ужасно злоупотребляют DbContext хотя. Эти вещи должны быть созданы как можно скорее и уничтожены как можно быстрее. – DavidG

+0

DbContext создается экземпляром контейнера DI, привязанным к HTTP-запросу. Я все еще полагаюсь на это, чтобы создать и уничтожить экземпляр DbContext. Если бы у меня были мои репозитории, сохраните изменения DbContext, этот экземпляр DbContext все равно не будет уничтожен, пока MVC не передаст ответ на следующий элемент в конвейере (поскольку он управляется контейнером DI таким образом по умолчанию, если я не ошибиться). Как мой подход отличается от этого? Да, DbContext будет создан немного раньше, но будет уничтожен одновременно, если бы я не использовал фильтр, не так ли? – iberodev

+0

Плюс Я не знаю другого способа обработки HTTP-запросов в транзакции типа стиля, не имея централизованного места ПОСЛЕ выполнения контроллера, чтобы все прошло нормально. Внедрение DbContext в контроллеры - это плохая идея, но в централизованном фильтре лучше подходит. Любое предложение для транзакционного подхода? – iberodev