Вы можете использовать IQueryable и принять, что кто-то может создать сценарий, в котором может произойти SELECT N + 1 . Это недостаток, а также тот факт, что вы можете получить код, специфичный для вашей реализации репозитория, на уровнях выше вашего репозитория. Преимущество этого состоит в том, что вы позволяете делегировать общие операции, такие как разбиение на страницы и сортировка, за пределами своего репозитория, что облегчает такие проблемы. Это также более гибко, если вам нужно объединить данные с другими таблицами базы данных, поскольку запрос останется выражением, поэтому его можно добавить до того, как он будет преобразован в запрос и попадет в базу данных.
Альтернатива - заблокировать ваш репозиторий, чтобы он возвращал материализованные списки, вызывая ToList()
. На примере разбивки на страницы и сортировки вам нужно будет передать в качестве параметров методы вашего репозитория параметры skip, take и sort, а также использовать параметры для возврата только окна результатов. Это означает, что хранилище берет на себя ответственность за разбиение на страницы и сортировку, а также за всю проекцию ваших данных.
Это довольно сложный вопрос, вы предоставляете приложению силу linq и имеете меньшую сложность в хранилище, или вы контролируете доступ к данным. Для меня это зависит от количества запросов, связанных с каждой сущностью и комбинаций сущностей, и от того, где я хочу управлять этой сложностью.