2011-04-01 108 views
0

我有一個組的列表,它屬於用戶對象:獲取多對多關係加載

public UserHeaderMap() 
{ 
    Table("USER_HEADER"); 
    Id(x => x.Id, "USER_ID"); 

    HasManyToMany(x => x.Groups) 
     .Table("USER_GROUP_COMPOSITE") 
     .ParentKeyColumn("USER_ID") 
     .ChildKeyColumn("GROUP_ID") 
     .Cascade.SaveUpdate() 
     .Inverse(); 
} 

如何我需要修改我的映射或辦法,我取回我的用戶對象以填充檢索後的組列表?我相信這裏有不同的選擇,但我不確定哪個是最好的。當我從數據庫中檢索用戶對象時,該集合當前爲空。我檢索它使用這樣的:

UserHeader userFound = session.Load<UserHeader>(newUser.Id); 

編輯:

public class UserHeader 
{ 
    public virtual Guid Id { get; set; } 
    public virtual IList<GroupHeader> Groups { get; set; } 

    public UserHeader(IList<GroupHeader> groups) 
    { 
     Groups = groups; 
    } 

    public UserHeader() 
    { 
     Groups = new List<GroupHeader>(); 
    } 

    public override bool Equals(object obj) 
    { 
     bool retVal = false; 
     if (obj is UserHeader) 
     { 
      UserHeader otherUser = (UserHeader)obj; 

      if (Id == otherUser.Id) 
       retVal = true; 
     } 

     return retVal; 
    } 

    public override int GetHashCode() 
    { 
     return Id.GetHashCode(); 
    } 
} 

EDIT2: 這是我最初的查詢數據的方式。除了多對多的關係之外,它抓住了一切。

UserHeader userFound = session.CreateCriteria<UserHeader>() 
           .Add(Example.Create(newUser)) 
           .UniqueResult<UserHeader>(); 

EDIT3:單元上的foreach測試 以下單元測試失敗(頁眉組userFound.Groups)。我可以從SQL中清楚地看到它正在SQL輸出中創建用戶和組之間的關係。如有必要,我可以發佈。

[TestMethod] 
public void CanAddUserToGroup() 
{ 
    using (NHibernate.ISession session = SessionOrigin.Current.GetSession()) 
    { 
     using (NHibernate.ITransaction tran = session.BeginTransaction()) 
     { 
      session.SaveOrUpdate(newUser); 
      session.SaveOrUpdate(newGroup); 
      tran.Commit(); 
     } 

     newGroup.AddUser(newUser); 
     using (NHibernate.ITransaction tran = session.BeginTransaction()) 
     { 
      session.SaveOrUpdate(newGroup); 
      tran.Commit(); 
     } 

     GroupHeader groupFound = session.CreateCriteria<GroupHeader>() 
      .Add(Example.Create(newGroup)) 
      .UniqueResult<GroupHeader>(); 

     UserHeader userFound = session.CreateCriteria<UserHeader>() 
      .Add(Example.Create(newUser)) 
      .UniqueResult<UserHeader>(); 

     UserHeader userFound2 = session.Load<UserHeader>(newUser.Id); 

     Assert.IsNotNull(groupFound, "Failed to find group after insertion"); 
     Assert.IsNotNull(userFound, "Failed to find user after insertion"); 

     UserHeader userInGroup = null; 
     GroupHeader groupInUser = null; 

     foreach (UserHeader user in groupFound.Users) 
     { 
      if (user.Equals(newUser)) 
       userInGroup = user; 
     } 

     foreach (GroupHeader group in userFound.Groups) 
     { 
      if (group.Equals(newGroup)) 
       groupInUser = group; 
     } 

     Assert.IsNotNull(userInGroup, "Failed to add a new user to group"); 
     Assert.IsNotNull(groupInUser, "Failed to add a new group to a user"); 

     using (NHibernate.ITransaction tran = session.BeginTransaction()) 
     { 
      session.Delete(newUser); 
      session.Delete(newGroup); 
      tran.Commit(); 
     } 
    } 
} 
+0

集合不應該爲空,它應該是空的。我們可以看到你的UserHeader POCO嗎? – 2011-04-02 01:23:54

+0

另外,'session.Load <>'不會導致從數據庫加載。它只獲得一個代理。 – 2011-04-02 12:46:35

+0

@Chad,我在上面添加了我的POCO。 – 2011-04-02 12:59:18

回答

1

您的單元測試代碼不正確。

由於組和用戶都已加載到會話中,因此條件查詢返回相同的實例。

如果集合在內存中爲空,它們在查詢後仍然爲空。此外,您只是添加到雙向關聯的一側。

最後但並非最不重要的一點,你正在同一測試方法中測試太多不相關的東西。

+0

中添加了我的單元測試我認爲,因爲我在控制檯輸出中看到SELECT查詢,所以它從數據庫中獲取用戶信息,而不是從會話中獲取。我是否必須創建一個新的會話來準確測試用戶是否被添加到組中? – 2011-04-03 19:22:07

+0

@ColeW:它查詢數據庫,但是當具有相同ID的同一類的對象出現時,它只是使用已加載的對象(這是Identity Map模式的正確行爲)。您可以從會話中「Evict()」原始對象,但使用不同的對象是首選。而且,實際上,您應該在測試設置中創建它們,而不是在測試方法中。 – 2011-04-03 22:42:03