2010-09-06 38 views
1

我有一個簡單的用戶和角色的NHibernate域模型。用戶和角色之間存在多對多關聯。簡化實體:NHibernate的問題多對多不更新實體

public class User : Entity<Guid> 
{ 
    private IList<Role> _roles; 

    public User() 
    { 
     _roles = new List<Role>(); 
    } 

    public virtual UserName { get; set; } 

    public virtual IList<Role> Roles { get; protected set; } 
} 

public class Role : Entity<Guid> 
{ 
    private IList<User> _users; 

    public Role() 
    { 
     _users = new List<User>(); 
    } 

    public virtual RoleName { get; set; } 

    public virtual IList<User> Users { get; protected set; } 
} 

基類有一個Id屬性。

的映射是這樣的:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     LazyLoad(); 
     Id(x => x.Id) 
      .GeneratedBy 
      .GuidComb(); 

     Map(x => x.UserName) 
      .Length(50) 
      .Not.Nullable() 
      .Unique(); 

     HasManyToMany(x => x.Roles) 
      .Cascade.SaveUpdate(); 
    } 
} 

public class RoleMap : ClassMap<Role> 
{ 
    public RoleMap() 
    { 
     LazyLoad(); 
     Id(x => x.Id) 
      .GeneratedBy.GuidComb(); 

     Map(x => x.RoleName) 
      .Length(20) 
      .Unique() 
      .Not.Nullable(); 

     HasManyToMany(x => x.Users) 
     .Cascade.SaveUpdate() 
     .Inverse(); 
    } 
} 

我讓FluentNH創建我的DDL和可以創建/更新/刪除用戶和角色。問題出在can_add_role_to_user()的單元測試中。簡化測試如下:

public void can_add_role_to_user() 
{ 
    var user = members.CreateUser(username); 
    var role = members.CreateRole(rolename, roledescription); 

    bool result = members.AddUserToRole (username, rolename); 

    // Assert 
    Assert.AreEqual (true, result); 
    var savedUser = members.GetUserByName(username); 
    Assert.IsNotNull(savedUser); 
    Assert.AreEqual (1, savedUser.Roles.Count); // Check role has been added to user 
    Assert.AreEqual (user, savedUser); 
    Assert.AreEqual (role, savedUser.Roles[0]); 

    var savedRole = members.GetRoleByName(rolename); 
    Assert.IsNotNull(newrole); 
    Assert.AreEqual(1, newrole.Users.Count); // Check user has been added to role - fails 
    Assert.AreEqual (role, newrole); 
    Assert.AreEqual (user, newrole.Users[0]); 
} 

第一組Asserts pass - 用戶中的IList有一個條目。然而,角色中的IList具有零條目。我知道我只能從用戶實體保存,因爲我在收集地圖上有反轉,但我希望NH能夠確保收集的兩側正確保溼,或者我錯過了某些東西。

+0

我不是一個FluentNH專家,但你確信這兩種關係使用相同的表嗎?還有哪些呢AddUserToRole做什麼?你什麼時候沖洗?如果你使用不同的會話來檢索已保存的角色會怎樣? – 2010-09-06 13:06:14

+0

Diego,Fluent正在使用約定來使表名在兩側保持一致 - 在這種情況下,它是RolesToUsers並使FK Role_id和User_id AddUserToRole是我的MembershipService中的一個方法,並獲取用戶並獲取角色,然後在SaveOrUpdate之前添加到IList中,沒有明確的刷新,只是纏繞在一個事務中,我將嘗試使用不同的會話。 – AndyB 2010-09-06 13:34:17

回答

1

會話刷新和清除的地方在哪裏? 你是否清除你的AddUserToRole方法和你的斷言之間的nhibernate會話?

可能是members.GetRoleByName(rolename)從標識映射中獲取角色。

+0

AddUserToRole方法具有Get 和SaveOrUpdate 。在Assert之前沒有隱式刷新或清除會話。 – AndyB 2010-09-06 13:07:13

+0

在Assert(1,newRole.Users.Count())和AreEqual和IsSame斷言通過之前,我稍微更改了Asserts並放置了Assert.AreEqual(role,newRole)和Assert.IsSame(role,newRole),但Count不。我在想,GetRoleByName是從身份映射中獲取的,因爲它們是AreEqual和IsSame。我在想我需要一個沖洗。 – AndyB 2010-09-06 13:12:24

0

我已經弄清楚雙向關係是怎麼回事。將角色添加到用戶NH的角色集合時,不會使關係的另一方。強制NH製作雙向的最簡單方法是清除ISession或驅逐兩個實體(我的首選)。這迫使NH訪問數據庫並正確構建關係的兩個方面。即newUser.Roles [0]包含添加的角色,newRole.Users [0]包含用戶 - 就像我想要的那樣。

我還發現,我的測試工具有一個bug,並創建兩個不同的會話:-(