2011-08-12 87 views
1

關於NHibernate級聯設置的文檔討論了在調用Save()Update()和Delete()方法的上下文中的設置。但是在隱式更新的上下文中,當我在同一個會話中加載,修改和保存實體時,我發現沒有關於級聯行爲的討論。在這種情況下,不需要顯式調用更新,那麼關於級聯設置會發生什麼?用於同一會話更新的NHibernate級聯行爲

這似乎是一個愚蠢的問題,但我提出這個問題的原因是,我試圖弄清楚NHibernate如何在域驅動設計的上下文中支持Aggregate Boundaries的概念。讓我舉一個例子來說明我想要了解的內容。

假設我有具有實體發票,買方和LineItem的規範發票應用程序。發票是一個聚合根,LineItem是在同一個聚合中,但買方是它自己的聚合根。

我想通過配置我的映射,使從發票到LineItem的級聯爲All-DeleteOrphans,並且從發票到買方的發票是None,在NHibernate中對此進行建模。

基於我已閱讀的文檔上,用我所希望的級聯的設置,如果我有斷開機構工作,我這樣做,只是發票和了LineItem節省:

disconnectedInvoice.ShippedDate = DateTime.Today(); 
disconnectedInvoice.LineItems[2].Backordered = true; 
disconnectedInvoice.Buyer.Address = buyersNewAddress; 

session.Update(disconnectedInvoice); 
session.Flush(); 

我不要什麼」在任何地方討論都會發生什麼,當人們檢索發票時,會以相同的方式進行相同的更新並刷新會話。

var invoice = session.Get<Invoice>(invoiceNumber); 
invoice.ShippedDate = DateTime.Today(); 
invoice.LineItems[2].Backordered = true; 
invoice.Buyer.Address = buyersNewAddress; 
session.Flush(); 

NHibernate的文檔說,刷新保持與會話相關的髒實體的變化。基於這個假設,發票,買方和LineItems的更新都將被保留。

但是,這似乎違反了層疊規則背後的概念。在我看來,爲了決定在刷新時更新哪些實體,會話應查看那些直接加載的實體(本例中僅爲發票)幷包含間接加載的實體(LineItems和此處的買方情況下)只有級聯設置表明他們應該堅持。

我承認這個例子代表壞DDD。如果買方不是彙總的一部分,那麼目前不應該更新。或者至少它不應該通過發票集合進行更新。但是,除了DDD之外,我實際上更感興趣的一點是確定級聯規則是否符合在同一會話場景中的更新,與在斷開連接的場景中相同。

回答

1

NHibernate文檔說明flush會保留與 會話關聯的髒實體的更改。

主要問題是斷開和連接實體之間的差異。級聯對於兩者來說都是相同的,但它是不同的隱式更新。對於會話加載的實體,不需要將保存級聯給買方,因爲它是多餘的。對於斷開的實體,您需要級聯,因爲該買方不會有任何隱式更新,因爲它從未明確地合併到會話中。

+0

這也是我閱讀文檔的方式。只是另一種方法似乎對我更有意義,在同一場景中我沒有看到有關更新級聯的任何明確討論。 –