Вопрос

Мы используем шаблон DTO для маршалирования объектов нашего домена с уровня сервиса в наш репозиторий, а затем в базу данных через NHibernate.

Я столкнулся с проблемой, из-за которой я извлекаю DTO из репозитория (например.CustomerDTO), а затем преобразовать его в объект домена (Customer) на моем уровне обслуживания.Затем я пытаюсь сохранить новый объект обратно (например.SalesOrder), который содержит тот же объект Customer.Он, в свою очередь, преобразуется в SalesOrderDTO (и CustomerDTO) для отправки в репозиторий.

NHibernate это не нравится — он жалуется, что CustomerDTO — дублирующаяся запись.Я предполагаю, что это связано с тем, что он извлек первый CustomerDTO в том же сеансе, и поскольку возвращаемые данные преобразовывались туда и обратно, он не может распознать это как один и тот же объект.

Я застрял здесь или есть способ обойти это?

Спасибо

Джеймс

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

Решение

Вы можете повторно присоединить объект к сеансу в NHibernate, используя Lock - например.

_session.Lock(myDetachedObject, NHibernate.LockMode.None);

что может помочь, а может и не помочь, в зависимости от того, что именно здесь происходит.Кстати, использование DTO с NHibernate — не самая распространенная практика. Тот факт, что NHibernate (в основном) поддерживает игнорирование персистентности, означает, что обычно DTO не так широко используются, как в некоторых других платформах ORM.

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

На самом деле речь идет о том, как работает сеанс NHibernate.Итак, если вы в течение сеанса извлекаете экземпляр своего CustomerDTO, а затем через некоторое время вы должны получить тот же самый CustomerDTO (скажем, по первичному ключу) - вы фактически получите ссылку на тот же самый объект, что и при первом извлечении.

Итак, вы либо объединяете объекты, вызывая session.Merge, либо запрашиваете объект у своего сеанса, вызывая session.Get(primaryKey), выполняете обновления и очищаете сеанс.

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

Как отмечали другие, реализация Equals и GetHashCode — это шаг в правильном направлении.Также обратите внимание на поддержку NHibernate идиомы «attach» OR/M.

В вашем распоряжении также есть опция Nosette.camelcase: http://davybrion.com/blog/2009/03/entities-required-properties-and-properties-that-shouldnt-be-modified/

Кроме того, я хотел бы призвать вас не разочаровываться из-за отсутствия информации в Интернете.Это не значит, что вы сумасшедший или делаете что-то неправильно.Это просто означает, что вы работаете в крайнем случае.К сожалению, крупнейшими потребителями таких библиотек, как NHibernate, являются небольшие собственные и/или веб-приложения, в которых существует возможность объединить все ваши потребности в постоянстве с одной базой данных.На самом деле из этого правила есть много исключений.

Например, в настоящее время я работаю над коммерческим настольным приложением, в котором данные одного из моих объектов домена распределены между базой данных SQL CE и файлами изображений на диске.К сожалению, NHibernate может помочь мне только с сохранением SQL CE.Я вынужден использовать своего рода «двойное сопоставление» (см. Мартин Фаулер «Образцы архитектуры корпоративных приложений».) сопоставьте мою модель домена через уровень репозитория, который знает, какие данные поступают в NHibernate, а какие на диск.

Бывает.Это реальная необходимость.Иногда очевидный недостаток инструмента указывает на то, что вы применяете плохой подход.Но иногда правда в том, что вы действительно находитесь в крайнем случае, и вам нужно выработать некоторые из этих шаблонов для себя, чтобы добиться цели.

Я предполагаю, что это потому, что он вытащил первого клиента в том же сеансе и потому, что возвращение было преобразовано взад и вперед, он не может распознать это как тот же объект.

Ты прав.Спящий режим не может.Чтобы исправить это, рассмотрите возможность реализации Equals и Hashcode.Я думаю, что повторное присоединение может сработать только в том случае, если вы не загрузили объект в этом сеансе.

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