Рекомендации MVC3 для сохранения вида с несколькими объектами
Предоставлено приложение MVC3 с использованием шаблона ViewModel и шаблона Repository с Entity Framework.
Если у меня есть представление создания и обновления, каждый из которых состоит из нескольких объектов, какова наилучшая практика для сохранения данных?
Должен ли я сохранить дату с использованием абстрактного сервисного уровня, который будет сохранять данные для каждого объекта с соответствующим репозиторием, или я должен сохранить данные в репозитории с помощью хранимой процедуры?
Я открыт для любых предложений или рекомендаций.
Заранее спасибо!
1 ответ
Это один из тех случаев, когда подход DDD/CQRS наиболее целесообразен. Проще говоря, у вас есть несколько бизнес-объектов, которые моделируют определенное поведение (совокупность). В chrage есть один объект под названием Aggregate Root (AR), который имеет явные границы. Когда вы хотите сохранить его, вы отправляете весь AR в хранилище, которое затем сохраняет все как транзакцию.
Рабочий процесс
Пользователь отправляет данные через модель представления. Затем контроллер получит AR из хранилища или создаст его, если он новый. Входные данные отображаются в AR, обычно с помощью метода AR. Если AR обнаруживает, что данные или их результат нарушают некоторые бизнес-правила, тогда он должен выдать исключение (мы предполагаем, что базовая проверка уже была выполнена автоматически asp.net mvc).
Если все в порядке, контроллер отправит AR в репозиторий, который затем перейдет к сопоставлению AR с сущностями EF и затем сохранит его, все в рамках транзакции.
Это в двух словах, как я это сделаю. Конечно, я бы реализовал это немного по-другому, но концепции были одинаковыми. Важной частью является отправка всех данных в AR, который будет знать, как обрабатывать отношения.
Важные моменты
Обратите внимание, что я упомянул EF только после того, как AR попал в репо. Это означает, что AR не имеет отношения к объектам EF, полностью отделен и служит фактически бизнес-модели. Только после обновления модели мы заботимся об EF и ТОЛЬКО в репо (поскольку EF - это деталь реализации репо). Репо только передает (в основном отображает) данные AR в соответствующие объекты EF, а затем сохраняет объекты.
Важно иметь очень четкое различие между бизнес-моделью (доменом) и моделью персистентности (сущности EF). Не используйте EF для обработки бизнес-правил, используйте его только для просмотра / извлечения данных из БД. EF был создан только для абстрагирования доступа к СУБД, используя его как виртуальную базу данных ООП.
Вы упомянули шаблон ViewModel. Я не слышал о такой схеме, каждый раз, когда вы используете MVC, вы уже используете ViewModels. Еще раз, уловка НЕ в том, чтобы использовать EF-сущности в качестве ViewModels. Используйте "тупые" модели, подходящие для видов. Заполните виртуальную машину через специализированный репозиторий запросов, который будет возвращать части виртуальной машины. Репо будет запрашивать объекты EF и затем возвращать те биты VM, которые являются простыми DTO. Это потому, что вам не нужны валидация и бизнес-правила при отображении данных.
Я думаю, что хорошей практикой является разделение слоев и особенно модели каждого слоя. Для обновления вещей используйте сложные бизнес-объекты (модель предметной области), которые выполнят тяжелую работу, а затем только передадут свое состояние в EF (через репозиторий). Для чтения материала запросите EF и верните простые DTO, подходящие для VM.
В этом и заключается суть CQRS: не пытайтесь совмещать разные обязанности (писать и читать) в одной модели.