Оба подхода возможны, и это только вопрос выбора.
Как только вы используете IQueryable
, у вас есть простой репозиторий, который будет работать в большинстве случаев, но он хуже тестируется, потому что запросы, определенные на IQueryable
, являются linq-to-entity.Если вы имитируете репозиторий, они являются linq-to-objects в модульных тестах = вы не тестируете свою реальную реализацию.Вам нужны интеграционные тесты для проверки логики запросов.
Как только вы используете IEnumerable
, у вас будут очень сложные общедоступные интерфейсы ваших репозиториев - вам потребуется специальный тип репозитория для каждой сущности, для которой требуется специальный запрос, представленный в репозитории.,Этот тип репозиториев более распространен в хранимых процедурах - каждый метод в репозитории был сопоставлен с одной хранимой процедурой.Этот тип репозитория обеспечивает лучшее разделение проблем и меньшую объемную абстракцию, но в то же время устраняет большую гибкость ORM и Linq.
В последнем случае вы можете использовать комбинированный подход, где у вас есть методы, возвращающие IEnumerable для наиболее распространенных сценариев (запросы используются чаще), и один метод, предоставляющий IQueryable
для редких или сложных динамически создаваемых запросов.
Редактировать:
Как отмечено в комментариях, использование IQueryable
имеет некоторые побочные эффекты.Когда вы выставляете IQueryable
, вы должны поддерживать свой контекст в активном состоянии до тех пор, пока не выполните запрос - IQueryable
использует отложенное выполнение таким же образом, как IEnumerable
, поэтому, если вы не вызовете ToList
, First
или другие функции, выполняющие ваш запрос, вывсе еще нужен ваш контекст.
Самый простой способ добиться этого - использовать одноразовый шаблон в хранилище - создать контекст в его конструкторе и утилизировать его при удалении хранилища.Затем вы можете использовать using
блоки и выполнять запросы внутри них.Этот подход предназначен для очень простых сценариев, когда вы довольны единым контекстом для каждого хранилища.Более сложные (и распространенные) сценарии требуют совместного использования контекста между несколькими репозиториями.В таком случае вы можете использовать что-то вроде провайдера контекста / фабрики (одноразового использования) и внедрить фабрику в конструктор репозитория (или разрешить провайдеру создавать репозитории).Это приводит к фабрике слоя DAL и пользовательской единице работы.