簡體   English   中英

NHibernate Definitive Cascade應用指南

[英]NHibernate Definitive Cascade application guide

是否有任何互聯網資源對NHibernate的所有級聯設置有明確的指導,其中包括類結構,HBM的示例以及與NH的所有關系的每個級聯設置的動作的含義。

如果有以最正確的方式進行公共關聯的示例,例如設置狀態表,您將永遠不會最終級聯刪除狀態,或者刪除具有CreatedBy用戶屬性的對象,那么它將會很有用。永遠不會在級聯等中刪除用戶

以下內容改編自NHiberate 3.0的Java Hibernate參考http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/objectstate.html#objectstate-transitive (即當前的svn trunk) 。

對於NHibernate會話的每個基本操作 - 包括Persist(),Merge(),SaveOrUpdate(),Delete(),Lock(),Refresh(),Evict(),Replicate() - 都有相應的級聯風格。 級聯樣式分別命名為persist,merge,save-update,delete,lock,refresh,evict,replicate。 Save()和Update()的級聯樣式是save-update; 對於SaveAndUpdateCopy(),它是合並; 對於PersistOnFlush(),它是持久的。 刪除是刪除的別名。

如果希望沿關聯級聯操作,則必須在映射文檔中指明該操作。 例如:

<one-to-one name="person" cascade="persist"/>

級聯風格我的組合:

<one-to-one name="person" cascade="persist,delete,lock"/>

您可以使用cascade =“all”指定所有操作都應該沿關聯級聯。 默認級聯=“none”指定不進行級聯操作。

特殊的級聯樣式delete-orphan僅適用於一對多關聯,並指示Delete()操作應應用於從關聯中刪除的任何子對象。 all-delete-orphan與all,delete-orphan相同。

建議:

  • 在<many-to-one>或<many-to-many>關聯上啟用級聯通常沒有意義。 Cascade通常用於<one-to-one>和<one-to-many>關聯。
  • 如果子對象的生命周期受父對象的生命周期限制,請通過指定cascade =“all-delete-orphan”將其設置為生命周期對象。
  • 否則,您可能根本不需要級聯。 但是如果你認為你經常在同一個交易中與父母和孩子一起工作,並且你想節省一些打字,可以考慮使用cascade =“persist,merge,save-update”。

使用cascade =“all”映射關聯(單值關聯或集合)將關聯標記為父/子樣式關系,其中父項的保存/更新/刪除導致保存/更新/刪除子項或兒童。 除非在使用cascade =“delete-orphan”映射的<one-to-many>關聯的情況下,否則不會自動刪除未被其父級引用的子級。 父/子關系的級聯操作的精確語義如下:

  • 如果將父級傳遞給Persist(),則所有子級都將傳遞給Persist()
  • 如果將父項傳遞給Merge(),則所有子項都將傳遞給Merge()
  • 如果將父級傳遞給Save(),Update()或SaveOrUpdate(),則所有子級都將傳遞給SaveOrUpdate()
  • 如果一個臨時或已分離的子進程被持久父進程引用,則將其傳遞給SaveOrUpdate()
  • 如果刪除父項,則將所有子項傳遞給Delete()
  • 如果孩子被持久父母取消引用,則不會發生任何特殊情況 - 應用程序應在必要時明確刪除子項 - 除非cascade =“delete-orphan”,在這種情況下,“孤立”子項將被刪除。

這可能是明顯的建議,但我建議瀏覽Ayende制作的舊帖子。 在他的網站上快速搜索 NHibernate和級聯顯示了一些有趣的帖子。 但是,它們可能對您的需求有點過於稀缺。

即使它本身不是互聯網資源,我也會推薦NHibernate in Action 它在第3,4和6章深入討論了級聯。本書針對NHibernate 1.2。 不過,我相信會有一本針對NHibernate 3.0版本的新版本。 可能值得關注。

盡管我希望看到一個關於級聯的權威指南,但我還沒有看到過。 也許你可以總結一些博客文章,在你自己的博客上用你自己的帖子討論級聯。

我不知道任何“權威”指南,但我知道的最好的資源是來自Ayende的博客文章,他是NHibernate的權威大師之一:

NHibernate Cascades:所有,all-delete-orphans和save-update之間的區別

對我來說,我實際上只使用cascade="none"cascade="all" all-delete-orphan有時是一個選項。 其他一切都是可疑的。 例如,為什么我應該隱式創建一個實例,因為它被引用,當它比包含對象長壽命時? 對我來說,只有兩種情況:對象是依賴對象還是獨立對象。

接受的答案詳細解釋了HBM文件。 這個答案涵蓋了按代碼映射的相同內容。 它們幾乎相同; 剛剛映射到他們的HBM字符串。

文章形式Ayende解釋得很好:

  • none - 不做任何級聯,讓用戶自己處理它們。
  • save-update - 保存/更新對象時,檢查關聯並保存/更新任何需要它的對象(包括在多對多方案中保存/更新關聯)。
  • delete - 刪除對象時,刪除關聯中的所有對象。
  • delete-orphan - 刪除對象時,刪除關聯中的所有對象。 除此之外,當從關聯中刪除對象而不與另一個對象(孤立對象)關聯時,也刪除它。
  • all - 當對象保存/更新/刪除時,檢查關聯並保存/更新/刪除找到的所有對象。
  • all-delete-orphan - 當一個對象被保存/更新/刪除時,檢查關聯並保存/更新/刪除找到的所有對象。 除此之外,當從關聯中刪除對象而不與另一個對象(孤立對象)關聯時,也刪除它。

此外, 這個問題解釋了Cascade一些內部實現。

 [Flags] public enum Cascade { None = 0, Persist = 2, Refresh = 4, Merge = 8, Remove = 16, Detach = 32, ReAttach = 64, DeleteOrphans = 128, All = 256, } private static IEnumerable<string> CascadeDefinitions(this Cascade source) { if (source.Has(Cascade.All)) { yield return "all"; } if (source.Has(Cascade.Persist)) { yield return "save-update, persist"; } if (source.Has(Cascade.Refresh)) { yield return "refresh"; } if (source.Has(Cascade.Merge)) { yield return "merge"; } if (source.Has(Cascade.Remove)) { yield return "delete"; } if (source.Has(Cascade.Detach)) { yield return "evict"; } if (source.Has(Cascade.ReAttach)) { yield return "lock"; } if (source.Has(Cascade.DeleteOrphans)) { yield return "delete-orphan"; } } 

請注意, Cascade.All不包括Cascade.DeleteOrphans 在這種情況下,您可能需要使用Cascade.All | Cascade.DeleteOrphans來包含它 Cascade.All | Cascade.DeleteOrphans

或者,您可以使用Include擴展方法Cascade.All.Include(Cascade.DeleteOrphans)

Cascade結合使用時,您可能還需要查看Inverse ; 它指定了協會的所有者。 有關詳細信息,請參閱問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM