2011-08-19 60 views
10

我試圖保存(插入)與列表子實體的父實體。這兩個實體都使用Guid作爲主鍵。密鑰不可爲空,並且在數據庫中沒有設置密鑰關係。同時插入NHibernate的父母和孩子

保存不起作用,引發異常聲明 - 我試圖將空值保存到Child表中的父外鍵中。

我期待nhibernate爲Parent創建一個鍵並讓它的Child對象知道它。這是NHibernate的限制還是使用Guid作爲主鍵?

answer建議你必須設置父手輪,這真的是唯一的方法嗎?

這裏是我的映射,以供參考:

父映射:

HasMany(x => x.Children).KeyColumn("ParentKey").Inverse().Cascade.All(); 

兒童映射:

References(x => x.Parent).Not.Nullable().Column("ParentKey"); 

回答

15

NHibernate的不是魔術。它只是一個ORM,如果你的孩子沒有對父母的引用,爲什麼會假設因爲父母有一個孩子的列表,這個孩子的引用反過來應該是對父母的引用?

我相信你回答了你自己的問題,當你聲明Child實體沒有填充Parent屬性時(這意味着它是null,這意味着NHibernate會試圖爲Parent id保存一個'null'值在您的子表中)。

如果你想在沒有NHibernate的情況下使用這些對象,那麼在添加父實體時需要在子實體上設置父引用。

編輯:這對於您所指定「逆」您映射的情況。如果您要將此呼叫移除至'Inverse'它應按照您希望其工作的方式工作指出另一端(子實體)負責跟蹤關係。這意味着您需要手動設置子對象的父對象的引用。

但是,刪除反向語句會導致保存Child(ren),保存父對象,然後將Child(ren)的父對象ID更新。由於您對父ID有空限制,這意味着它仍然無法正常工作,因爲它最初會將父ID用於空插入。

兩個解決辦法是要麼刪除此約束,或只加一個方法叫的AddChild父:

public void AddChild(Child childObj) 
{ 
    childObj.Parent = this; 
    Children.Add(childObj); 
} 

添加另一種方法稱爲removeChild之:

public void RemoveChild(Child childObj) 
{ 
    if (Children.Contains(childObj)) 
    { 
     Child.Parent = null; 
     Children.Remove(childObj); 
    } 
} 

然後,只需使用這些方法添加/刪除兒童。

+1

當然,我並不希望保存前的引用在運行時存在(也許我的問題是誤導,不適當編輯它) - 我期待的是Nhibernate知道父和子都是新的,並且知道如何用適當的鑰匙來堅持他們......太多問了嗎? – Dan

+0

@丹我已經更新了我的答案,以提供更多幫助。 – docmanhattan

+0

只是解釋更多的映射和約束檢查此鏈接http://wiki.fluentnhibernate.org/Fluent_mapping#Access_strategies – cpoDesign

相關問題