2010-11-05 83 views
4

我想知道什麼樣的最佳設計是用NHibernate持久化一個新的子實體,而不會意外覆蓋數據庫中的父項。NHibernate:如何保存一個新的實體,而不覆蓋父:

我的問題是,孩子實體將是這個樣子:

class Child 
{ 
    Parent Parent; 
    // other fields 
} 

我的問題是,孩子已經從UI層與母公司的ID一起提供,這意味着Parent ref基本上是未初始化的:它將填充ID,但其他一切都爲空 - 因爲填充其字段的唯一方法是額外往返數據庫以讀取它們。

現在,如果我在NHibernate上調用Session.SaveOrUpdate(child),父類會發生什麼情況。我不希望NHibernate級聯保存未初始化的父節點,因爲這隻會破壞數據庫中的數據。人們會如何解決這個問題?任何最佳實踐?

回答

0

如果你的模型看起來像這樣

class Parent 
{ 

} 


class Child 
{ 
    Parent myParent; 
} 

,你試圖設置家長和救孩子不有一個完整的父對象,只是ID。

你可以試試這個:

session.Lock(child.myParent, LockMode.None); 

保存前,這應該告訴NHibernate的,有沒有更改父對象持久化,它應該只看對象爲ID堅持之間的關聯父母和子女

1

您應該在進行保存(或SaveOrUpdates等)時使用聚合根(可能是Parent)。

爲什麼不乾脆:

  • 使用從UI層
  • 在孩子有父ID取父對象的孩子加入到父母的孩子們收集
+0

好的謝謝。這意味着需要額外往返數據庫才能獲取父項,即使我並不打算對父數據執行任何操作,但我更願意避免使用這些數據。沒有什麼好方法可以避免這種情況? – PhantomDrummer 2010-11-05 11:28:05

+0

建議使用Load()作爲Trygve以避免加載不必要的數據。 – UpTheCreek 2010-11-05 12:03:23

+1

聽起來似乎正在發生的事情是,孩子正在通過查詢直接填充到用戶界面中,而不考慮父母。正在提出的是一種設計的一般原則,即你從未在父母之外擁有子女。你肯定不會在沒有經過父母的情況下添加新的孩子。 – Sisyphus 2010-11-05 12:29:43

3

您必須使用session.Load(parentid)來獲取聚合根。與session.Get()方法不同,它實際上並不從數據庫中獲取任何數據,它只是實例化一個Parent代理對象,用於將Child對象添加到數據庫中正確的Parent中(例如正確獲取外鍵) 。

您的代碼可能會是這個樣子:

// Set the Parent to a nhibernate proxy of the Parent using the ParentId supplied from the UI 
childFromUI.Parent = Session.Load<Parent>(childFromUI.Parent.Id); 
Session.Save(childFromUI); 

This article explains Get/Load and the nhibernate caches really well

+0

+1;有趣的鏈接,但我發現http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx更簡潔的參考獲取與負載的區別。 – Marijn 2010-11-05 12:50:52

+0

有趣,謝謝 – PhantomDrummer 2010-11-05 16:12:25

1

我認爲你必須概覽你的映射配置 nhibernate。如果您已經定義了孩子對父母的參考信息,那麼您必須將所有信息級聯起來,它會更新它! 所以如果你說Cascade.None他什麼都不會做。其他都是壞主意。因爲你已經有了這個父母的信息。那麼爲什麼要從db agane讀取?!

相關問題