Entity Framework Core 1.0 единица работы с промежуточным программным обеспечением Asp.Net Core или фильтром Mvc

Я использую EF Core 1.0 (ранее известный как EF7) и ASP.NET Core 1.0 (ранее известный как ASP.NET 5) для RESTful API.

Я хотел бы, чтобы некоторая единица работы была ограничена запросом http таким образом, чтобы при ответе на запрос HTTP либо ВСЕ изменения, внесенные в DbContext, были сохранены в базе данных, либо ни одно не было сохранено (если было какое-то исключение, например).

В прошлом я использовал WebAPI2 для этой цели с NHibernate, используя фильтр действий, в котором я начинаю транзакцию при выполнении действия, а при выполнении действия я завершаю транзакцию и закрываю сеанс. Это был способ, рекомендованный наhttp://isbn.directory/book/9781484201107

Однако сейчас я использую Asp.Net Core (с Asp.Net Core Mvc, хотя это не должно быть актуально) и Entity Framework, которая, как я понял, уже реализует единицу работы.

Я думаю, что промежуточное ПО, подключенное к конвейеру ASP.NET (до MVC), было бы правильным способом сделать что-то. Таким образом, запрос будет идти:

ТРУБОПРОВОД ASP.NET:MyUnitOfWorkMiddleware ==> Контроллер MVC ==> Репозиторий ==> Контроллер MVC ==> MyUnitOfWorkMiddleware

Я думал о том, чтобы это промежуточное ПО сохраняло изменения DbContext, если не произошло исключений, так что в моих реализациях репозитория мне даже не нужно делатьdbcontext.SaveChanges() и все будет как централизованная транзакция. В псевдокоде, я думаю, это будет что-то вроде:

class MyUnitOfWorkMiddleware
{
     //..
     1-get an instance of DbContext for this request.
     try {
         2-await the next item in the pipeline.
         3-dbContext.SaveChanges();
     }
     catch (Exception e) {
         2.1-rollback changes (simply by ignoring context)
         2.2-return an http error response
     }
}

Имеет ли это смысл? У кого-нибудь есть пример чего-то похожего? Я не могу найти хорошую практику или рекомендации по этому поводу.

Кроме того, если я использую этот подход на уровне контроллера MVC, у меня не будет доступа к любому идентификатору ресурса, созданному базой данных при отправке нового ресурса, поскольку идентификатор не будет сгенерирован до тех пор, пока не будут сохранены изменения dbContext (позже в конвейере). в моем промежуточном ПО ПОСЛЕ завершения выполнения контроллера). Что если мне нужно было получить доступ к вновь созданному идентификатору ресурса в моем контроллере?

Любой совет будет принята с благодарностью!

ОБНОВЛЕНИЕ 1: Я обнаружил проблему с моим подходом к использованию промежуточного программного обеспечения для достижения этой цели, поскольку экземпляр DbContext в промежуточном программном обеспечении отличается от времени жизни MVC (и репозиториев). Смотри вопросEntity Framework Core 1.0 DbContext не ограничен запросом http

ОБНОВЛЕНИЕ 2:Я еще не нашел хорошего решения. В основном это мои варианты до сих пор:

Сохраните изменения в БД как можно скорее. Это означает сохранение его в самой реализации репозитория. Проблема с этим подходом состоит в том, что для запроса Http, возможно, я хочу использовать несколько репозиториев (то есть: сохранить что-то в базе данных, а затем загрузить большой двоичный объект в облачное хранилище), и чтобы получить единицу работы, мне нужно было бы реализовать репозиторий, который имеет дело с более чем одним объектом или даже более чем одним методом персистентности (БД и хранилище BLOB-объектов), который наносит ущерб всей цели

РеализоватьФильтр действий где я завернуть все выполнение действия в транзакции БД. В конце выполнения действия контроллера, если нет исключений, я фиксирую изменения в БД, но если есть исключения, я откатываю и отбрасываю контекст. Проблема в том, что для действия моего контроллера может потребоваться сгенерированный Id сущности, чтобы вернуть его http-клиенту (то есть: если я получу POST / api / cars, я хотел бы вернуть 201 Accepted с заголовком местоположения, который идентифицирует новый ресурс, созданный в / api / cars / 123 и Id 123, еще не будет доступен, поскольку объект не был сохранен в БД, а Id все еще является временным 0). Пример действия контроллера для запроса глагола POST:

return CreatedAtRoute("GetCarById", new { carId= carSummaryCreated.Id }, carSummaryCreated); //carSummaryCreated.Id would be 0 until the changes are saved in DB

Как я мог иметь полное действие контроллера, завернутый в транзакцию БД и в то же время иметь доступ к любому идентификатору, сгенерированному базой данных, чтобы вернуть его в Http Response от контроллера? Или же..Есть ли какой-нибудь элегантный способ перезаписать HTTP-ответ и установить Id на уровне фильтра действий после того, как изменения БД были зафиксированы?

ОБНОВЛЕНИЕ 3: СогласноnathanaldensrКомментарий Я мог бы получить лучшее из обоих миров (обернуть выполнение действия моего контроллера в транзакции БД _ UoW, а также узнать идентификатор нового ресурса, созданного еще до того, как БД фиксирует изменения), используя сгенерированные кодом направляющие, вместо этого полагаясь на базу данных для генерировать гид.

Ответы на вопрос(3)

Ваш ответ на вопрос