2011-07-25 65 views
3

我可能在這裏做一個新手的錯誤,但我無法弄清楚如何使這項工作。我有兩個實體 - ParentChild,其中一個Parent可以有許多Child ren。問題似乎是,當我向父項添加新子項時,父項不能級聯保存子項,因爲子項實例尚未具有ID。在另一方面,孩子不能在自己的堅持,所以它沒有獲得一個ID的方式...NHibernate的堅持爲了增加對象集合

我的映射:

public ParentMap() 
{ 
    // ID and other properties 

    HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad(); 
} 

public ChildMap() 
{ 
    // ID and other properties 

    References(c => c.Parent); 
} 

現在,我可能已經有一個父記錄在我的數據庫中,並且我想將一個孩子添加到其子集合中。爲此,我創建了一個Child類的新實例,將該子項添加到父項的Children屬性(類型爲IList<Child>)。我還獲取父記錄並將子女Parent屬性設置爲父實體。

當我試圖挽救這個,我得到的錯誤,無論我嘗試做順序。

隨着Save(p),節約父記錄,希望孩子將被保存在級聯,我得到以下錯誤:

Cannot insert the value NULL into column 'ChildID', table 'dbo.Children'; column does not allow null values. INSERT fails. The statement has been terminated.

如果我試着在其他的方式,即先救孩子,然後加入它的母公司和保存的父母,我得到以下錯誤:

null id in Application.Domain.Entities.Child entry (don't flush the Session after an exception occurs)

按照什麼順序我應該叫parent.Children.Add(child)child.Parent = parentsession.Save(parent)session.Save(child),使這個工作?我的映射配置中是否缺少某些東西?

更新:我添加.Inverse(),並嘗試沒有成功如下:

// First of the above errors 
session.Save(child); 
child.Parent = parent; 
parent.Children.Add(child); 
session.Save(parent); 

// Second of the above errors 
child.Parent = parent; 
parent.Children.Add(child); 
session.Save(child); 
session.Save(parent); 

// Second of the above errors 
child.Parent = parent; 
parent.Children.Add(child); 
session.Save(parent); 

// Second of the above errors 
child.Parent = parent; 
parent.Children.Add(child); 
session.Save(child); 

回答

0

原來,NHibernate根本不是這個問題,而是我的數據庫配置 - 我忘記了配置Children表的ID列。只要我指定ID列,一切都按預期工作:不需要.Inverse(),我可以只保存ParentChild級聯保存。

0

標記您的父母的一側Inverse關係。這會說NHibernate的那個孩子的側管理的關係:

HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse(); 

這將迫使你手動設置child.Parent = parent,但你無論如何做,所以我相信這不是一個問題。

默認情況下,NHibernate的假定它的父的責任來設置對孩子的外鍵。和操作的邏輯順序看某種程度上是這樣的:

  1. 家長要保存
  2. 兒童由於保存級聯 - 我們沒有父ID,但(至少我們不能有,我不知道爲什麼它的工作原理是,當我們知道它,太)
  3. 孩子們在家長的外鍵
  4. 家長與null插入,然後插入成功,其ID被取出
  5. 孩子有父母的外鍵更新。

在你的第一種情況下,它沒有在3號,因爲你沒有可以空的外鍵列和NHibernate不夠聰明,找到任何解決方案。

設置Inverse()告訴家長不關心子外鍵,您有責任正確設置child.Parent。保存在這種情況下,只有插入,如預期的那樣,並且不會嘗試在外鍵中設置null

+0

隨着'.Inverse()'如你所說,我仍然得到完全相同的錯誤。 –

0

我失蹤Cascade.All()References。我們不應該把Inverse()HasMany

public ParentMap() 
{ 
    // ID and other properties 

    HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad(); 
} 

public ChildMap() 
{ 
    // ID and other properties 

    References(c => c.Parent).Cascade.All(); 
}