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

Каков наилучший подход для обновления только измененных свойств в NHibernate при отключении сеанса?

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

Например, когда мне нужно получить объект из базы данных, я открываю сеанс, а затем вызываю session.Get() и закрываю сеанс. Затем я обновляю некоторые свойства отдельного объекта. Когда мне нужно сохранить изменения в базе данных, я вызываю метод, который открывает сеанс, вызывает session.Update(myObject) и закрывает сеанс.

Но когда я это делаю, NHibernate генерирует sql, который обновляет все поля, которые я отобразил, даже если они не изменились. Мое предложение - когда объекты отрываются от сеанса, NHibernate не смог отслеживать изменения. Какой подход вы используете, если хотите обновить только те свойства, которые были изменены для объекта, отделенного от сеанса? Как вы отслеживаете изменения для отдельных объектов?

Спасибо

4b9b3361

Ответ 1

Вопрос: зачем вы хотите это делать? Я думаю, что это не большая оптимизация, если вы только обновляете измененные столбцы.

У вас есть триггеры в базе данных?

Если это так, вы можете сделать следующее:

  • используйте select-before-update="true" и dynamic-update="true" в отображении. Это делает NH для выполнения запроса перед обновлением и только обновления, если он изменился, и только те столбцы, которые были изменены. Я не уверен, что он выбирает для каждого обновления или только если он не находится в сеансе.
  • используйте Merge вместо обновления. Это фактически то же самое: он выбирает объект из базы данных, только если он еще не находится в сеансе. Также используйте dynamic-update="true". Существует также компромисс: Merge возвращает прикрепленный экземпляр, если в сеансе уже есть один. Поэтому вы всегда должны отбрасывать экземпляр, в который вы проходили, и работать с экземпляром, который вы отправляете из Merge.

На самом деле мне не нужны обновленные столбцы. Скорее всего, быстрее обновить их вслепую вместо выполнения предыдущего запроса.

Ответ 2

Используйте dynamic-update = "true" в mapping.
Кроме того, для обновления отдельного объекта используйте это:

Session.SaveOrUpdateCopy(myObject)