Вопрос

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

, другими словами: должны ли службы делать различные запросы Linq to SQL в репозитории? Или все запросы должны быть предопределенными в репозитории, и бизнес-логика просто решает, какой метод вызывать?

Это было полезно?

Решение

Вы фактически подняли здесь вопрос, который в настоящее время вызывает много дискуссий в сообществе разработчиков - см. последующие комментарии к Должен ли мой репозиторий предоставлять IQueryable?

Хранилище может - и должно - создавать сложные комбинированные объекты, содержащие несколько связанных объектов. В дизайне, управляемом доменом, они называются агрегатами - коллекциями связанных объектов, организованными в некую связную структуру. Ваш код не должен вызывать GetCustomer () , GetOrdersForCustomer () , GetInvoicesForCustomer () - вы просто вызываете myCustomerRepository. Загрузите (customerId) , и вы получите глубокий объект customer с уже созданными экземплярами этих свойств. Я также должен добавить, что если вы возвращаете отдельные объекты на основе определенных таблиц базы данных, то это совершенно правильный подход, но на самом деле это не репозиторий per se - это просто слой доступа к данным.

С одной стороны, есть убедительный аргумент, что объекты Linq-to-SQL с их «умными» свойствами и их отложенным выполнением (т.е. без загрузки Customer.Orders, пока вы на самом деле не используете его), являются полностью допустимой реализацией шаблон репозитория, поскольку на самом деле вы не выполняете код базы данных, вы выполняете операторы LINQ (которые затем преобразуются в код БД базовым поставщиком LINQ)

С другой стороны, как отмечается в посте Мэтта Бриггса, L2S довольно тесно связан с вашей структурой базы данных (один класс на таблицу) и имеет ограничения (например, нет много-много отображений) - и вы можете быть лучше отключите использование L2S для доступа к данным в вашем хранилище, но затем сопоставьте объекты L2S с вашими объектами модели домена и верните их.

Другие советы

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

Если вы используете этот тип паттерна, вы можете подумать о L2S. Он генерирует слой доступа к данным для вас, но на самом деле не обрабатывает несоответствие импеданса, вы должны сделать это вручную. Если вы посмотрите на что-то вроде NHibernate, то это отображение будет сделано более надежным способом. L2S - это больше для двухуровневого приложения, где вам нужен быстрый и грязный DAL, который вы можете легко расширить.

Если вы используете LINQ, то я считаю, что хранилище должно быть контейнером для вашего синтаксиса LINQ. Это дает вам уровень абстракции подпрограмм доступа к базе данных от интерфейса вашей модели. Как упоминал Дилан выше, существуют и другие взгляды на этот вопрос, некоторые люди предпочитают возвращать IQueryable, чтобы они могли продолжать запрашивать базу данных на более позднем этапе после репозитория. В любом из этих подходов нет ничего плохого, если вы четко указали свои стандарты для своего приложения. Существует больше информации о лучших практиках, которые я использую для репозиториев LINQ здесь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top