Шаблон DbContextScope для EF Core 3

Некоторые из вас могут быть знакомы с библиотекой DbContextScope, которая позволяет вам вкладывать области в код, и разрешить этим областям использовать общий DbContext. Идея состоит в том, что DbContext управляется за вас библиотекой области видимости, и вместо вызова SaveChanges () в контексте вы вызываете SaveChanges () в области. Волшебство происходит потому, что область видимости будет сохранять все изменения в контексте только при внешнем вызове SaveChanges (), поэтому все вложенные операции, выполняемые в DbContext, сохраняются в одной транзакции на уровне внешней области.

Теперь, когда DI является первоклассным гражданином .NET Core, кажется, что области видимости также стали важной частью экосистемы .NET Core, и команда EF Core, зная об этом, реализовала область видимости, основанную на разрешении внедрения DbContexts с помощью система DI и (я предполагаю) позволяет сохранять изменения на уровнях области видимости, а не каким-то образом непосредственно в DbContexts.

Итак, мой вопрос таков:

  • Каков соответствующий способ совместного использования DbContext через область, позволяющий управлять SaveChanges () на уровне области, а не на уровне кода, который обычно вызывает SaveChanges () в DbContext?
  • Есть ли в EF Core новые механизмы, которые управляют этим за вас, так же, как DbContextScope сделал это для вас как сторонняя библиотека?
  • Спасите меня от драмы и избавьте меня от лекций о том, почему, по вашему мнению, UOW необходимо внедрить в дополнение к EF. Спасибо, до свидания.

ОБНОВЛЕНИЕ: по состоянию на 6/2020 существует несколько форков DbContextScope, которые работают с EF Core 3.

ОБНОВЛЕНИЕ: Форки этого проекта можно посмотреть здесь: https://github.com/mehdime/DbContextScope/network

Существует несколько версий EF Core 3 ... Я еще не пробовал, но готово.


person Rafe    schedule 02.01.2020    source источник
comment
Думаю, можно смело придерживаться DbContextScope. AmbientContext (шаблон проектирования, которому он следует) является подходящим решением здесь, как и для TransactionScope.   -  person Timo    schedule 18.06.2020
comment
@Rafe - re: есть несколько форков DbContextScope, которые работают с EF Core 3. Можете ли вы поделиться ссылками на то, какие форки заявили о поддержке? Спасибо.   -  person Derek Bromenshenkel    schedule 10.07.2020
comment
@DerekBromenshenkel См. Второе обновление выше.   -  person Rafe    schedule 18.07.2020
comment
@Rafe, какие вилки вы используете для работы с EF Core 3?   -  person guaike    schedule 16.08.2020
comment
@guaike, честно говоря, я еще не обновился. Мне любопытно узнать, использовал ли кто-нибудь одну из вилок EF Core 3.   -  person Rafe    schedule 01.10.2020


Ответы (2)


Начиная с Entity Framework 5.0.0, есть IDbContextFactory<TDbContext>, который позволяет вам контролировать создание и удаление (!!) ваших DbContexts.

Вместо регистрации DbContext с AddDbContext или AddDbContextPool теперь вы можете использовать AddDbContextFactory или AddPooledDbContextFactory соответственно.

Обратите внимание, что эта функция решает одну из проблем, которые решает DbContextScope, а не все из них. Что касается других проблем и решений, обратитесь к исходному сообщению Мехди. Он длинный, но отличный.

person Timo    schedule 01.10.2020

Совместное использование DbContext встроено в конструкцию внедрения зависимостей для EF.

Контейнер DI сгенерирует экземпляр DbContext с заданной областью для каждого веб-запроса. Вы можете поделиться экземпляром DbContext из любого компонента, который от него зависит, и вызвать SaveChanges () или управлять транзакциями во внешнем контроллере.

person David Browne - Microsoft    schedule 02.01.2020
comment
Итак, вы предлагаете ввести DbContext в мой контроллер и вызвать там сохранение изменений ??? Похоже, это наихудшее место для управления операциями с данными. Это удручает. - person Rafe; 02.01.2020
comment
Вы можете управлять UoW где угодно. DI просто обработает время жизни DbContext за вас. - person David Browne - Microsoft; 02.01.2020
comment
Значит, в функциональности области нет ничего, что автоматически вызывало бы сохранение изменений? - person Rafe; 02.01.2020
comment
Вы можете создать промежуточное ПО, которое будет обертывать запрос и вызывать сохранение изменений в конце вызова. - person grinay; 03.01.2020
comment
Проблема в том, что факт того, что DbContext доступен в контейнере, ничего не говорит вам о том, действительно ли текущий код вызывается внешним кодом, который знает об этом, т.е. это вызовет SaveChanges для вас. С DbContextScope он всегда присутствует только в том случае, если внешний код сознательно создал его, что означает, что либо кто-то берет на себя ответственность за вызов SaveChanges, либо вы получаете исключение из-за отсутствия области. Обычный DI с ограниченной областью видимости этого не имеет, что, на мой взгляд, делает его недостаточным. - person Timo; 18.06.2020
comment
@David Browne - суть шаблона DbContextScope состоит в том, чтобы позволить вам явно контролировать время жизни DbContext (ов). Например, в рамках одного веб-запроса у вас может быть две бизнес-транзакции, каждая из которых имеет отдельный DbContextScope. Поправьте меня, если я ошибаюсь, но, по-видимому, нет способа получить такой уровень контроля с помощью встроенной инфраструктуры внедрения зависимостей .NET Core? - person Zejji Zejji; 22.09.2020
comment
Внедрение dbcontext кажется рецептом катастрофы. Я удивлен, что это вообще разрешено. Если вы сделаете что-нибудь в другом потоке / задаче и т. Д., Ваше приложение сломается. Это может работать для основных веб-приложений, но не более того. - person Chris Johnson; 10.04.2021