бизнес-уровень с несколькими объектами, все свойства которых заполнены из БД, или один объект, заполненный только подмножество
Вопрос
Я создаю систему среднего размера и столкнулся с проблемой, с которой, возможно, некоторые из вас сталкивались раньше.На моем бизнес-уровне я возвращаю бизнес-объекты с подмножеством свойств, которые важны для этого бизнес-метода. Я беспокоюсь, потому что в конечном итоге я могу получить слишком много объектов с бессмысленными именами или только один, в котором в заданном объеме будет заполнено только подмножество свойств. метод.Позвольте мне привести пример.
Дело 1
Например, пользователь принадлежит городу, который, в свою очередь, принадлежит штату и стране. User
, City
, State
и Country
В моей базе данных есть таблицы с большим количеством полей, но мне нужен список пользователей со списком заказов, поэтому я создаю бизнес-объект, например UserWithOthers
только с важными свойствами (UserId, UserName, CityName, StateName, CountryName, List<Order>
), и мой DAL извлекает из базы данных только эти поля.
Случай 2
Теперь я хочу вернуть пользователя с количеством заказов, в моем бизнес-объекте я заканчиваю следующими полями (UserId, UserName, CityName, StateName, CountryName, OrdersCount
) и класс можно вызвать, например UserWithOrderCount
Я продумывал несколько вариантов:
- Создайте два бизнес-класса и заполните их отдельно в каждом методе DAL (эти объекты просты, но учтите, что метод может иметь сложный запрос выбора, который необходимо инкапсулировать для повторного использования, поэтому шаблон репозитория сюда не подходит, по крайней мере, я думаю, что ).
- Создать только один объект
User
со всеми свойствами(UserId, UserName, CityName, StateName, CountryName, OrdersCount, List<Order>
) и заполнять только подмножество в каждом методе DAL, но это подразумевает семантическую связь при использовании метода, поскольку вы должны знать, какое подмножество полей заполняется из базы данных, а семантическая связь — худшая из всех связей. - Вариант 1 не подходит, если мне понадобится позже другое представление, оба,
List<Order>
иOrdersCount
характеристики. - Учтите теперь, что если вы используете хорошие практики ASP.NET MVC, которые говорят, что вам нужна ViewModel для перехода к представлению, я подумал вернуть ViewModels из моего бизнес-слоя, но я не думаю, что это хорошая идея, такое ощущение, что я что-то нарушаете, а также это невозможно, поскольку мой бизнес-уровень находится в другой сборке, а не в веб-приложении.
- Я не хочу писать один и тот же запрос Linq снова и снова, но если использовать NHibernate или EFCodeFirst, это «как» первый вариант, и мне нужно будет создать множество объектов малого бизнеса.
Как вы справляетесь с этой ситуацией?Я думаю, что это дизайнерское решение высокого уровня.
Решение
Прежде всего, я определенно согласен с вами насчет некоторых вещей, которые делать нельзя:
Не заполняйте бизнес-объекты частично, так как ответственность за знание того, какие свойства заполняются, ложится на клиентов бизнес-уровня, что является очень плохой практикой.
Не возвращайте ViewModels со своего бизнес-уровня;Предполагается, что ваш бизнес-уровень представляет бизнес-концепции домена вашего приложения, а ViewModel — это объект данных, который содержит данные, необходимые для отображения определенного представления одной части этого домена — это две очень разные вещи, и бизнес-уровень должен совершенно не осознавать, что его бизнес-объекты используются в любом графическом интерфейсе.
Я бы согласился с вашим первым предложением — создать один отдельный бизнес-объект для представления каждой бизнес-концепции.Затем я бы использовал ORM (например, EF или NHibernate) для заполнения этих объектов с помощью выделенных репозиториев для каждой группы объектов.Затем я бы использовал уровень приложения, который вызывает репозитории для возврата любых необходимых объектов.с этой целью ваш репозиторий может включать методы, которые возвращают объединенных пользователей и заказы в тех случаях, когда вы знаете, что вам нужно использовать эти два типа вместе.Это позволяет вам возвращать Пользователя со всеми его Заказами в одном запросе, сохраняя при этом отдельные значимые сущности для представления Пользователей и Заказов.