2010-11-02 72 views
2

我有一個父子關係,我已經把測試用例放在用戶和用戶組之間。我這樣做是爲了在嘗試使用關係執行cacade插入時複製父親 - 子女關係中的故障 。流利NHibernate父子級聯SaveOrUpdate失敗

兩個SQL表如下所示:

CREATE TABLE [dbo].[User] 
(
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    [Name] [varchar](50) NOT NULL, 
) 
CREATE TABLE [dbo].[Group] 
(
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    [GroupName] [varchar](50) NOT NULL, 
    [UserId] [int] NOT NULL, 
) 

ALTER TABLE [dbo].[Group] WITH CHECK ADD CONSTRAINT [FK_Group_User] FOREIGN KEY([UserId]) 
REFERENCES [dbo].[User] ([Id]) 

的對象表示這兩個表具有以下映射:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Table("[User]"); 
     Id(x => x.Id).GeneratedBy.Identity(); 
     Map(x => x.Name).Not.Nullable(); 
     HasMany(x => x.Groups).KeyColumn("UserId").Cascade.SaveUpdate(); 
    } 
} 

public class GroupMap : ClassMap<Group> 
{ 
    public GroupMap() 
    { 
     Table("[Group]"); 
     Id(x => x.Id).GeneratedBy.Identity(); 
     Map(x => x.GroupName).Not.Nullable(); 
     References(x => x.User).Column("UserId").Not.Nullable(); 
    } 
} 

的代碼創建的對象僅僅是:

用戶u =新用戶(){姓名=「測試」}; Group g = new Group(){GroupName =「Test Group」}; u.Groups.Add(g);

using (var session = factory.OpenSession()) 
    { 
     session.SaveOrUpdate(u); 
    } 

但是它失敗,出現異常「無法將NULL值插入列‘用戶ID’,表‘test.dbo.Group’;列不允許空INSERT失敗 的語句已終止。」。我懷疑這是dude父對象的Id(一個標識列)作爲NULL傳遞,而不是新的值。這是一個錯誤還是有辦法解決這些映射,以便這個級聯關係成功?

回答

3

你必須先保存用戶然後將該組分配給用戶,並保存:

using (var session = factory.OpenSession()) 
    { 

User u = new User() { Name = "test"}; 
    session.SaveOrUpdate(u); 

Group g = new Group() { GroupName = "Test Group", User = u }; 
session.SaveOrUpdate(g) 


} 

我發現,你不能級聯保存這只是剛剛創建父/子相關的對象。

+1

這正是我所做的解決方法。不過,我會認爲這種親子關係是相當普遍的,因此會得到照顧。 – Dion 2010-11-02 19:48:43

4

我最近有這種確切類型的映射在一個項目中工作正常。我的建議是:

  • 瞭解HasMany關係的Inverse屬性如何工作。 Great explanation here
  • 您需要父對象和子對象之間的雙向關聯。這在上面鏈接的文章的底部進行了解釋。

另一個好的建議是更好地封裝您的收藏 - 不要直接訪問您的收藏修改方法。集合屬性應該是隻讀的,父類(在你的情況下是用戶類)應該有改變私有集合的AddGroup()和RemoveGroup()方法。爲了這個工作,你必須讓NHibernate通過使用.Access.CamelCaseField(Prefix.Underscore)或類似的映射屬性來訪問私有集合成員。 Good discussion about it here

如果需要,我可以發佈示例映射和類文件。

+0

+1,因爲反向是IMO的方式 – Firo 2012-03-01 16:54:26