Это зависит от мнения и варианта использования, но я лично не согласен с некоторыми из упомянутых вами ключевых моментов.
Возврат IEnumerable вместо IQueryable
Согласен.Возвращение IQueryable
побеждает основную цель существования Репозитория.В сети много статей, объясняющих, как это создает больше проблем, чем решений.Хотя я научился никогда не говорить никогда.См. это , это или это .Или просто выполните поиск google .
Репозиторий должен взять на себя ответственность только за операции CRUD
Согласен.С простым CRUD, он также может выполнять сложные операции чтения и записи.Мой опыт показывает, что в исключительных случаях вы должны поместить часть бизнес-логики в хранилище, если вы хотите реализовать ее на стороне СУБД.Это не правильно или неправильно.Если вы знаете, что делаете, проблем не должно быть.
Возвращаемый тип метода репозитория: модель (сущность)
Если вы не используете DDD, тогда да.В противном случае это решение о реализации.При использовании полной ORM, такой как EF или NHibernate, лучше возвращать модель домена напрямую, а не для каждого экземпляра таблицы Entity.
Всегда рекомендуется, чтобы репозиторий возвращал модель домена.Таким образом, отображение данных, возвращаемых из RDBMS с помощью модели предметной области (и наоборот), становится обязанностью репозитория.Это избавляет от необходимости вытекать проблемы постоянства за пределы репозитория и, таким образом, делает вашу постоянную целостность приложения невежественной.
Но не каждое приложение реализует DDD.Многие малые приложения проектируют сущности, которые отображаются с 1 на 1 в своей структуре базы данных.В этом случае репозиторий может вернуть саму сущность (которая эквивалентна вашей таблице и полям), и отображение становится ответственностью вызывающего кода.Или хранилище может отобразить необходимую модель и вернуть саму модель.Это настоятельно не рекомендуется, потому что проблемы, указанные выше.При этом вам придется отказаться от некоторых функций, которые предоставляют полные ORM.
Все это зависит от вашей проблемы, ваших целей проектирования, размера приложения и других реализованных шаблонов проектирования и т. Д. Вот почемуэто становится проектным решением.
Реализуйте репозиторий только для объединенного корня
Согласовано, если это с DDD.Если нет, доступно несколько вариантов, например, для каждого хранилища таблиц.Опять же, зависит от варианта использования.
О сложном запросе
Нет необходимости в том, чтобы в репозиториях использовались только простые методы CRUD.Также может возвращать сложный граф объектов.Это может сделать сложные запросы.Тем не менее, с простыми методами, такими как Get
, GetById
и т. Д., Он также может использовать сложные методы, такие как GetTopBrokenVehicles(vehicleType, top)
.Это совершенно нормально, если вы пишете отдельный метод для сложного запроса.
Проблема заключается в том, как вы принимаете необходимые параметры.Вы можете принять параметры встроенными или создать отдельный простой класс входных параметров.
Вот пример кода для Хранилище и UoW .