Организационно, где я должен поставить общие запросы при использовании Entity Framework Code First?

Я выкладываю новый слой данных, используя EF 4.1 Code First, переходя со старого слоя данных homebrew.

Я установил две сборки, одну для моего контекста и одну для всех первых классов кода POCO.

У меня есть бизнес-логика, например, запрос к одной таблице (или нескольким таблицам), которая используется в нескольких разных местах. Где я должен положить это?

Он не может входить в класс POCO, потому что он объединяет пару таблиц и поэтому нуждается в контексте. Это может идти в контексте, но этот контекст станет раздутым с сотнями неорганизованных запросов. Существует ли общая схема или схема всей бизнес-логики?

3 ответа

Решение

Похоже, что шаблон хранилища - это решение для всего... Репозиторий - это не серебряная пуля!

Я использую шаблон репозитория с EF каждый день, потому что когда я начал свой текущий проект несколько месяцев назад, он выглядел как рекомендуемое решение. Мои выводы:

  • Хранилище значительно усложняет взаимодействие с EF. Просто просмотрите вопросы, связанные с тегами EF, и вы увидите, какие сложности нужно решать непосредственно в контексте, отслеживании изменений и т. Д.
  • Универсальный репозиторий - это то, что работает для операций CRUD, но не для реальных сценариев DDD. Как только ваш репозиторий работает с агрегатными корнями (DDD), общий подход не работает.
  • Модульное тестирование не работает вообще, потому что общая идея, что вы будете имитировать репозиторий и тестировать свой верхний уровень без зависимостей от EF, и база данных завершится неудачно, как только вы выставите IQueryable, Linq-to-entity является лишь подмножеством Linq-to-objects, и mock не обрабатывает ссылочную целостность так много раз, что я видел зеленые модульные тесты и исключения во время выполнения. Правильный подход к тестированию с EF - это интеграционные тесты. Репозиторий Mocking предназначен только для тестирования реальной бизнес-логики, не связанной с доступом к данным. Если у вас нет интеграционного теста для доступа бизнес-метода или к сохранению данных, вы его не тестировали.
  • Разоблачение специализированных методов, таких как GetByXXX, просто шаг назад. Большинство из этих методов используются только один раз. Вы закончите с кодом, похожим на репозитории, используемые для упаковки вызовов хранимых процедур. Многим разработчикам нравится ORM только потому, что они могут избежать такой жесткой архитектуры.

Сам EF уже предлагает шаблон хранилища - DbSet а также ObjectSet репозитории и DbContext а также ObjectContext Единица работ. Так что, по моему мнению, шаблон репозитория чрезмерно используется. Это может быть полезно в больших проектах, где вам нужна строгая многоуровневость, или в случае размещения дополнительной логики для ее методов. Использование репозитория только потому, что вы хотите обернуть доступ к EF, часто является бесполезным кодом и просто дополнительным уровнем сложности.

Таким же образом вы можете создавать повторно используемые методы, определяющие ваши запросы.

Я бы использовал Шаблон репозитория. Ниже приведен пример использования кода EF и MVC Entity Framework 4 CTP 4 / CTP 5 Общий шаблон репозитория и модульное тестирование

Вот некоторые хорошие чтения по шаблону:

Также может быть хорошей идеей взглянуть на Domain Driven Design (DDD), так как вы начинаете с доменной модели.

Некоторые хорошие чтения на DDD:

Если вы используете EF непосредственно в бизнес-методах (службы уровня домена и службы уровня приложения), то вы не изолируете уровень модели домена от технологий инфраструктуры (в данном случае EF). Это один из принципов DDD. у вас, вероятно, должен быть один репозиторий на агрегат.

Для получения дополнительной информации о DDD, см.:

Книга Эрика Эванса: http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215

Microsoft: http://msdn.microsoft.com/es-es/architecture/en

Другие вопросы по тегам