В простейших примерах, когда у вас есть метод GET и POST в контроллере, и ничего более, нет никакой разницы между использованием Transient и Per-Request. Когда приходит Per-Request, ваш контроллер переключается на другие классы для выполнения соответствующей работы. Типичным примером является шаблон репозитория, но на самом деле также применим любой класс службы / помощника, который централизует общее поведение. Если DbContext является Transient, и вы вызываете одну из этих служб, передавая объект, который контроллер извлек из DbContext, и эти службы обращаются к DbContext, они будут использовать экземпляр DbContext, отличный от того, который сделал Контроллер. Это может привести к довольно раздражающим проблемам с отслеживанием сущностей и попытками вставить повторяющиеся строки, потому что экземпляр DbContext контроллера не отслеживает сущности, которые могли быть загружены другим DbContext и связаны с сущностью, отслеживаемой экземпляром контроллера. Используя экземпляр для каждого запроса, любой связанный класс, который запрашивает DbContext, получит тот же экземпляр, который устраняет эти проблемы.
Даже если все операции находятся в некотором роде c друг от друга, наличие одного экземпляра означает, что все эти изменения будут зафиксированы или откатаны вместе. Хотя это, как правило, желаемое поведение, само по себе это может привести к неожиданным проблемам, поскольку возникает вопрос о том, когда следует вызывать SaveChanges
? Когда у вас есть контроллер, вызывающий различные распространенные методы, и DbContext ограничивается для каждого запроса, если любой из этих методов вызывает SaveChanges
, все, что было сделано до этого момента, будет пытаться зафиксировать в БД. Таким образом, вы можете столкнуться с проблемами, когда вы вызываете 3 общих сервисных метода, каждый из которых вызывает SaveChanges, первые 2 успешно завершаются без проблем, а 3-й сбой. Как правило, вы ожидаете, что Контроллер будет иметь последнее слово для выполнения фиксации и обработки исключений. В этих случаях может быть полезно использовать Единицу Работы, чтобы «заключить» в DbContext и гарантировать, что решение о фиксации или откате DbContext поддерживается на самом высоком уровне операции. Таким образом, UoW может быть ограничено в начале запроса (т. Е. Метод контроллера), а вспомогательные службы и т. Д. c. получить ссылку на DbContext от UoW, но контроллер получает последнее слово, если / когда вызывается UoW SaveChanges.