Шаблон проектирования для сопоставления DTO, содержащих дочерние коллекции, с моделями доменов - PullRequest
20 голосов
/ 03 января 2011

Долгое время я использовал AutoMapper для сопоставления моих моделей доменов с моими DTO, а также для сопоставления моего DTO с моделями доменов.

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

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

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

Ответы [ 4 ]

3 голосов
/ 01 апреля 2011

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

1 голос
/ 17 января 2011

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

Я думаю, что в NHibernate есть похожая опция каскада.

1 голос
/ 01 апреля 2011

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

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

  1. Используйте ConstructWith, чтобы вытащить сущность из базы данных, используя идентификатор dto.
  2. Используйте BeforeMap, чтобы ОЧИСТИТЬ всю дочернюю коллекцию (убедитесь, что для ссылки на дочерний элемент также будет установлено значение null).
  3. AutoMapper автоматически скопирует новую коллекцию.

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

1 голос
/ 04 января 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...