Переопределить поведение удаления в NHibernate - PullRequest
4 голосов
/ 07 апреля 2010

В моем приложении пользователи не могут по-настоящему удалять записи. Вместо этого в поле «Удаленные» записи устанавливается значение 1, что скрывает его от выбора.

Мне нужно сохранить это поведение, и я проверяю, подходит ли NHibernate для моего приложения. Могу ли я переопределить поведение удаления NHibnernate, чтобы вместо выполнения операторов DELETE он выдавал UPDATES, как описано выше?

Мне, очевидно, также необходимо переопределить его поведение SELECT, чтобы включить предложение 'AND Deleted = 0'. Или вместо этого читайте из представления. Я не уверен.

Ответы [ 3 ]

12 голосов
/ 07 апреля 2010

Чтобы реализовать мягкое удаление, просто обойдите механизм удаления Hibernate. Вместо этого сопоставьте поле Deleted вашей таблицы с логическим свойством .Net с тем же именем. Чтобы удалить элемент, установите item.Deleted = true. Затем добавьте атрибут where в сопоставление классов, чтобы отфильтровать удаленные элементы. Если хотите, создайте еще одно сопоставление для удаленных элементов. В противном случае они станут невидимыми для вашего приложения, но, возможно, это то, что вы хотите.

Редактировать: Вот, возможно, лучший подход: используйте тег <sql-delete>, чтобы написать пользовательскую операцию удаления для вашего отображения. См. http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html#querysql-cud. Я думаю, что это в сочетании с атрибутом where будет просто билет. Например:

<class name="MyClass" table="my_table" where="deleted=0">
  ...
  <sql-delete>UPDATE my_table SET deleted=1 WHERE id=?</sql-delete>
</class>
4 голосов
/ 07 апреля 2010

Я реализовал это, используя триггеры INSTEAD OF DELETE на SQL Server, чтобы установить бит флага удаления при выдаче SQL DELETE. Это имеет два преимущества: 1) Я могу просто выдавать удаление из моего приложения. без беспокойства и 2) Он обеспечивает мягкое удаление для всего доступа к базе данных (т. е. триггер должен быть временно отключен для жесткого удаления). Затем я настроил представления, которые выбирают только активные записи и сопоставляют их с NHibernate. Это решение очень хорошо сработало для меня.

2 голосов
/ 07 апреля 2010

Я думаю, что лучший способ получить такое поведение - реализовать интерфейс IInterceptor, который позволит вам выполнять собственный код, как показано в Документация NHibernate .

В противном случае вы можете просто создать триггер при удалении, который будет выполнять обновление. Это решение проще, но подходит ли оно для ваших нужд?

Что касается SELECT, вам нужно только написать метод, который будет использовать Criterion с предложением Where, чтобы указать вещь Deleted = 0.

...