2010-07-13 152 views
0

我們有一個非常深的對象圖,我們需要一種方法來刪除對象圖的根,它需要快速發生。我們正在談論約10-15個表格中的1000行。我們還將所有收藏映射爲AllDeleteOrphan。我們跳過NH將執行外鍵刪除,但它實際上執行刪除集合中的每個項目。你如何處理這樣的情況?NHibernate和級聯刪除

+0

我沒有足夠的nhibernate的知識,但我想知道是否(或更可能*爲什麼*)這不能僅通過SQL中的級聯刪除來完成? – annakata 2010-07-13 15:02:57

+0

@annakata:它可以,但AllDeleteOrphan具有這樣的語義,即當從收集中刪除項目時,它將生成刪除語句。 – epitka 2010-07-13 15:04:40

+0

是的,我只是不知道我是否相信效率:)如果依賴關係被SQL丟棄,但對象表示在NHibernate中被持久化顯然是最終不好的,但如果發生這種情況,我不會當然。基本上,使用nhibernate是否阻止你調用SQL行爲? – annakata 2010-07-13 15:15:37

回答

0

我相信你感興趣的on-delete="cascade"屬性;看樣映射:

<set name="Children" table="Child" cascade="save-update" lazy="true" inverse="true"> 
     <key column="ParentId" not-null="true" on-delete="cascade" /> 
     <one-to-many class="Child" /> 
    </set> 

在此的幾個注意事項:

  1. 這僅適用於關係的逆側
  2. 您可以使用訪問=「沒有做到這一點相同的映射「如果它乾淨地與你的域模型不匹配(如果你使用模式導出生成你的db,這仍然會創建適當的級聯刪除)

如果你想保持這種行爲compl在對象模型中,我建議查看this post,其中討論了使用收集事件偵聽器執行一次性刪除操作。

+0

事件監聽器方法看起來非常有前途。我們會測試它,看看它的行爲如何 – epitka 2010-07-13 17:24:57

2

在你需要做的批量操作的情況下,你可能想直接在服務執行一些HQL/SQL。 ORM工具提供了很多便利,但有時候它更好地直接處理sql。我們有一個類似的情況,我們不得不做一個對象圖的深層副本 - 花10分鐘休眠,並用我剛纔描述的方法2秒...

編輯 - ive想過你的關注「泄露域外的任何信息「,我想你的意思是你不想混淆擔憂。通過我描述的方法,您仍然可以正確分離您的疑慮 - 我說過將hql方法放在服務中,但我的意思是可以在DAO中完成。所有持久性代碼在一個地方。

在我們的情況,我們花了很多時間試圖調整休眠,並設法使其更快。當一個高級分貝傢伙告訴我,只是做它在HQL,花了大約4個小時適當測試,以實現它做....你真的應該考慮這種方法來節省時間......

+0

這當然是一個選擇,只是不在我們的情況下,因爲我們不想泄露域外的任何東西。 – epitka 2010-07-13 17:23:42

+0

@epitka - 我不明白你的意思是「泄漏我們的域名以外的任何東西」。你應該可以直接使用hql來做到這一點,所以你仍然可以在休眠狀態下運行。 – hvgotcodes 2010-07-13 18:15:33

+0

我也發現hql通常莫名其妙地更快。有時要快得多 – Alistair 2010-07-14 11:46:42