Как обновить объект с ленивыми свойствами (прокси-объект) в другом сеансе?

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

Я использую NHibernate 3.4. Когда я гуглил, я узнал, что это ошибка, которая была исправлена.

Я также натолкнулся на этот пост, в котором говорится, что если ваш прокси-объект реализует INhibernateProxy, вы можете отменить прокси-объект с помощью NHibernate. Поскольку NHibernate больше не поддерживает подключаемые прокси-фабрики (такие как Castle, LinFu и т. Д.), Он использует внутреннюю, я предполагаю, что внутренней, возможно, является INhibernateProxy.

Итак, я сделал следующее в новой сессии, где я хочу обновить свой объект как:

 object unprox_obj = Session
     .GetSessionImplementation()
     .PersistenceContext.Unproxy(secUserobj);

в ожидании получения этого же объекта, но с реальным типом, т.е. SecUser, чтобы он мог обновляться без каких-либо ошибок. Но он все еще возвращает объект прокси.

Я не могу понять, что происходит?

Обновлено: я только что понял, что secUserobj не INhibernateProxy. Итак, как я могу сделать это INhibernateProxy для обновления моего объекта в другой сессии?

 if (secUserobj is INHibernateProxy)
 {
     unprox_obj = Session
        .GetSessionImplementation()
        .PersistenceContext.Unproxy(secUserobj);
 }

1 ответ

Решение

Отдельные объекты (загруженные в одном сеансе и сохраненные в качестве ссылки) могут быть повторно присоединены. Мы можем использовать session.Merge() или же session.Lock()

9.4.2. Обновление отдельных объектов

Многим приложениям необходимо извлечь объект в одной транзакции, отправить его на уровень пользовательского интерфейса для манипуляции, а затем сохранить изменения в новой транзакции....

...

... последнего случая можно избежать, используя Merge(Object o), Этот метод копирует состояние данного объекта в постоянный объект с тем же идентификатором. Если в данный момент нет постоянного экземпляра, связанного с сеансом, он будет загружен. Метод возвращает постоянный экземпляр. Если данный экземпляр не сохранен или не существует в базе данных, NHibernate сохранит его и вернет как новый постоянный экземпляр. В противном случае данный экземпляр не становится связанным с сеансом. В большинстве приложений с отсоединенными объектами вам нужны оба метода, SaveOrUpdate() а также Merge(),

19.1.4. Инициализация коллекций и прокси

...
Вы также можете прикрепить ранее загруженный объект к новой ISession с помощью Merge() или же Lock()перед доступом к неинициализированным коллекциям (или другим прокси). Нет, NHibernate не делает и, конечно, не должен делать это автоматически, так как он вводит специальную семантику транзакций!
...

Таким образом, мы можем передать отдельную ссылку в .Merge(), а затем работать с возвращенной (совершенно новой) ссылкой на объект:

MyEntity reAttached = session.Merge<MyEntity>(detached);

Будьте осторожны, это должно быть сделано (как указано выше) до того, как какая-либо отдельная коллекция была затронута.

Другие вопросы по тегам