2010-04-07 45 views
4

在我的應用程序中,用戶不能真正刪除記錄。相反,記錄的「已刪除」字段被設置爲1,從而避免了選擇。覆蓋NHibernate中的刪除行爲

我需要保持這種行爲,我正在研究NHibernate是否適合我的應用程序。我可以重寫NHibnernate的刪除行爲,以便發出DELETE語句,而不是發出UPDATES,如上所述?

我當然也需要重寫它的SELECT行爲以包含'AND Deleted = 0'子句。或者從視圖中讀取。我不確定。

回答

2

我覺得讓這樣的行爲是通過實現IInterceptor接口,這樣可以讓你的NHibernate Documentation中所示執行自己的代碼的最佳方式。

否則,您可以簡單地創建一個刪除觸發器來執行更新。這個解決方案更簡單,但這是否適合您的需求?

至於SELECT,你只需要編寫將使用Criterion和Where子句來指定Deleted = 0的方法。

+0

我正在考慮更多地使用攔截,而不是像以前的答案那樣避免使用刪除功能。最終它取決於我認爲實施每種方法的難易程度。 感謝大家! – David 2010-04-07 15:55:09

+0

還有一個DeleteEventListener可以用來覆蓋正常的刪除行爲。 http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/08/soft-deletes.aspx – David 2010-04-08 12:36:23

+0

這是特別有趣的事情!感謝提示! =) – 2010-04-08 13:15:41

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> 
+0

+1對於類映射元素中的Where屬性。沒有想到它自己。謝謝! =) – 2010-04-07 15:38:39

+0

謝謝!我不知道你可以在類映射中添加一個where屬性。我會看看! – David 2010-04-07 15:53:59

4

我使用SQL Server上的INSTEAD OF DELETE觸發器實現了此功能,以在發出SQL DELETE時設置刪除標誌位。這有兩個好處:1)我可以從我的應用程序發出刪除。無需擔心,並且2)爲所有數據庫訪問強制執行軟刪除(即,觸發器必須暫時禁用以硬刪除)。然後我設置了視圖,只選擇活動記錄並將NHibernate映射到這些視圖。這個解決方案對我來說工作得非常好。

+0

這是一個不錯的解決方案 - 我特別喜歡軟數據刪除功能在數據庫中而不是在應用程序本身的層中實現的事實。但是,您必須爲每個表創建一個觸發器和一個視圖!這是一個嚴重的缺點。 – David 2011-01-05 16:40:05

+0

我們只在幾張桌子上進行軟刪除,並讓其他應用程序觸及數據庫,因此這對我們來說是一種安全而簡單的方法。 – 2011-01-05 19:06:27