Подтвердить что ты не робот

Шаблон проектирования для сопоставления DTO, содержащих дочерние коллекции, для моделей домена

В течение самого длительного времени я использую AutoMapper для сопоставления моделей моего домена с моими DTO, а также для отображения моего DTO на модели домена.

Я использую EF4 для своего ORM, и это сопоставление становится действительно уродливым, когда отображаемая модель содержит дочерние коллекции, которые необходимо добавить/обновить/удалить. Когда я продвигаюсь вперед с моим проектом, я все чаще сталкиваюсь с этой проблемой: фотографии для сообщения в блоге, пакеты для заказа и т.д.

При переходе от модели домена DTO- > мне нужно добавить вызов BeforeMap, который удаляет все сущности из коллекции модели домена, а затем добавляет пользовательский ValueResolver для коллекции, которая принимает PK каждого объекта из DTO, захватывает его из БД (так что Entity Framework не думает, что я добавляю новый объект), и повторно добавляет его в коллекцию модели домена, а затем применяю любые обновления для отдельных полей.

Это действительно уродливое решение, но также мои попытки вручную обрабатывать обновления этих коллекций. Есть ли у кого-нибудь предложения по более чистному подходу?

4b9b3361

Ответ 1

Вы можете использовать ValueInjecter вместо AutoMapper для этой функции. Посмотрите на этот вопрос, где производители обоих взвешивают AutoMapper vs ValueInjecter. Я лично не использовал Value Injecter, но он был создан, чтобы делать то, что вы пытаетесь сделать. AutoMapper лучше подходит для выравнивания, но автор AutoMapper признает, что он не является хорошим инструментом для "Unflattening", что вы пытаетесь сделать.

Ответ 2

Из-за очень плохого опыта с обновлением графа отдельных объектов я всегда сначала загружаю фактический граф объектов из базы данных и вручную объединяю свой DTO в этот граф объектов. Обычно я получаю несколько вспомогательных классов слияния с методами, объединяющими DTO (или модели просмотра) с объектами Domain. Я все еще ищу лучшее решение.

Я также попробовал решение, где я сначала не загружал граф объектов из базы данных. Вместо этого я использовал пользовательские адаптеры для построения отдельного графа объектов домена, привязал его к контексту и задал состояния всех объектов и отношений. Но это был неправильный и чрезвычайно сложный способ, который нельзя было использовать для всех сценариев (комбинация обновлений и вставки сущностей не могла быть обработана без дополнительных переданных данных о начальном состоянии).

Ответ 3

В спящем режиме есть опция каскада, в которой обновления от детей.

Я думаю, что NHibernate имеет аналогичный вариант cascadeAll.

Ответ 4

Если вы можете передать, исходя из предположения, что детская коллекция DTO вероятно, самая обновленная версия, вы можете фактически заменить старый коллекция с новой.

У нас была такая же проблема с NHibernate и мы решили это следующим образом:

  • Используйте ConstructWith, чтобы вытащить объект из базы данных, используя dto id.
  • Используйте PreMap для очистки всей дочерней коллекции (убедитесь, что ссылка на ребенка также будет установлена ​​равной нулю).
  • AutoMapper автоматически скопирует новую коллекцию.

К счастью, NHibernate был достаточно умен, чтобы применять изменения только, я не могу скажите, делает ли EF то же самое. Это не идеальное решение, но оно работает для простой модели домена.