я понял, наблюдая это видео с Роуэн Миллер 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 закачиваемой будет такой же ..
Я думаю, вы ужасно злоупотребляют DbContext хотя. Эти вещи должны быть созданы как можно скорее и уничтожены как можно быстрее. – DavidG
DbContext создается экземпляром контейнера DI, привязанным к HTTP-запросу. Я все еще полагаюсь на это, чтобы создать и уничтожить экземпляр DbContext. Если бы у меня были мои репозитории, сохраните изменения DbContext, этот экземпляр DbContext все равно не будет уничтожен, пока MVC не передаст ответ на следующий элемент в конвейере (поскольку он управляется контейнером DI таким образом по умолчанию, если я не ошибиться). Как мой подход отличается от этого? Да, DbContext будет создан немного раньше, но будет уничтожен одновременно, если бы я не использовал фильтр, не так ли? – iberodev
Плюс Я не знаю другого способа обработки HTTP-запросов в транзакции типа стиля, не имея централизованного места ПОСЛЕ выполнения контроллера, чтобы все прошло нормально. Внедрение DbContext в контроллеры - это плохая идея, но в централизованном фильтре лучше подходит. Любое предложение для транзакционного подхода? – iberodev