在我的应用程序中,用户无法真正删除记录。而是将记录的Deleted字段设置为1,将其隐藏在选择中。
我需要保持这种行为,我正在研究NHibernate是否适合我的应用程序。我可以覆盖NHibnernate的删除行为,这样它就会发出更新,而不是发出DELETE语句,如上所述吗?
我显然还需要覆盖其SELECT行为以包含“AND Deleted = 0
”子句。或者从视图中读取。我不确定。
答案 0 :(得分:12)
实现软删除只是绕过了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>
答案 1 :(得分:4)
我使用SQL Server上的INSTEAD OF DELETE触发器实现了这一点,以便在发出SQL DELETE时设置删除标志位。这有两个好处:1)我可以从我的应用程序发出删除。无忧无虑2)它强制所有数据库访问的软删除(即必须暂时禁用触发器以进行硬删除)。然后我设置视图,仅选择活动记录并将NHibernate映射到那些。这个解决方案对我来说非常有用。
答案 2 :(得分:2)
我认为获得此类行为的最佳方法是实现IInterceptor接口,该接口允许您执行NHibernate Documentation中显示的自己的代码。
否则,您只需在删除时创建一个执行更新的触发器。这个解决方案更简单,但这是否适合您的需求?
对于SELECT,你只需要编写将使用Criterion和Where子句来指定Deleted = 0的方法。