Доля DbContext через репозитории в MVC Web App
вопрос
каков правильный способ совместного использования EF DbContext в нескольких репозиториях в веб-приложении MVC? Разумно / необходимо ли это делать, каковы подводные камни этого или нет?
фон
допустим:
- App.MvcSite (несколько десятков контроллеров, несколько областей и т. д.)
- App.Услуги (уровень обслуживания, множество услуги)
- App.Данные (много репозиториев и т. д.)
- ... etc исключен для простоты (код EF первый последний)
На
Я, кажется, нахожу по крайней мере две/три школы мысли о SO и interwebs.
- Share / scope ваш DbContext к запросу чтобы один запрос имел один DbContext, общий для всех репозиториев.
- поделиться/область DbContext на уровне сервиса -- служба поддерживает один DbContext и передает его в каждый репозиторий по мере необходимости.
- не делитесь DbContext, так как они дешевы пусть каждый РЕПО имеет свой собственный.
на небольшом веб-сайте это не проблема, поэтому большинство примеров MS и сообщества просто даже не обращаются к этому.
по моему опыту до сих пор я не использовал конечных хранилищ. У меня всегда были услуги использовать DbContext и непосредственно изменить его, поэтому мне не нужно было беспокоиться об этом. Мне сказали, что с точки зрения модульного тестирования существует большое преимущество для конечных репозиториев... посмотрим, оправдает ли это все остальное.
Мои Мысли
(1) Share / scope ваш DbContext к запросу
Это интересно, поскольку он ловко избегает ловушки одноэлементного контекста, который некоторые разработчики считают ответом, но находят DbContext не работает таким образом. Но, похоже, у него есть недостаток в том, что он предполагает, что все репозитории, службы и т. д. будут согласованы по всему запросу... это часто не так, верно? Что делать, если изменения сохраняются одним РЕПО до того, как другой завершит свою работу. (внешний (внутренний (внутренний)))
(2) Share / scope ваш DbContext на уровне сервиса
это имеет больше смысла для меня, потому что каждая служба должна быть координация конкретной единицы работы (нижний регистр намеренно). Поэтому, если в одном запросе используется несколько служб, было бы правильно (если не требуется), чтобы каждая имела свой собственный контекст для базы данных.
(3) не делитесь DbContext, так как они дешевы
это то, как я всегда это делал... ну, на самом деле у меня почти всегда был только один DbContext на запрос, потому что вызывалась только одна служба. Иногда их может быть двое. потому что две службы были вызваны контролером, который координировал работу. Но, учитывая мое текущее приложение, со многими конечными репозиториями, каждый репозиторий, имеющий свой собственный контекст, будет означать, что данный запрос может иметь 3-10 экземпляров DbContext. Я предполагаю (возможно, неправильно), что это проблематично.
повторив вопрос:
каков правильный способ совместного использования EF DbContext в нескольких репозиториях в веб-приложении MVC? Это благоразумно / необходимо сделать это, каковы подводные камни делать или не делать этого?
2 ответов
-
DbContext
дешевы, но распределенные транзакции-нет. - объекты, прикрепленные к одному контексту, не могут использоваться в другом контексте (если у вас есть объектные отношения)
самый простой способ поделиться контекстом-начать использовать инверсию контейнера управления: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci
Я бы пошел на комбинацию между первыми двумя вариантами и относительно вашего подхода к первому варианту, не позволяйте репозиториям сохранять какие-либо изменения (это не рекомендуемый способ делать вещи, Мартин Фаулер говорит, что он сам), и для этого он представил шаблон единицы работы.