映射用户,角色和RolePermissions

时间:2011-10-19 02:12:20

标签: c# nhibernate fluent-nhibernate

我有以下实体:

User
Role

然后是连接表:

UsersRoles (UserId, RoleId)

然后是RolePermissions表:

RolePermissions(Id, RoleId, ....)

所以在我希望能够做的用户实体上:

user.Roles
user.RolePermissions

我的UserMap看起来像:

public class UserMap : ClassMap<User>
{
   public UserMap()
   {

      HasManyToMany(x => x.Roles)
            .Table("RolesUsers")
            .Access.CamelCaseField(Prefix.Underscore)
            .ParentKeyColumn("UserId")
            .ChildKeyColumn("RoleId")
            .Cascade.All()
            .Inverse();
   }

}

现在我创建了一个新用户:

var user = new User { ... };
user.AddRole(new Role { .... } );

UserRepository.Create(user);

它会保存用户并保存角色,但不会插入到RolesUsers表中?

另外如何添加属性以获取用户的所有RolePermissions?

更新

我的角色地图有:

 HasManyToMany(x => x.Users)
            .Table("RolesUsers")
            .Access.CamelCaseField(Prefix.Underscore)
            .ParentKeyColumn("RoleId")
            .ChildKeyColumn("UserId")
            .Cascade.All();

我的单元测试确实通过了,但我认为这是因为我不知道如何清除第一级缓存,它甚至不会通过调用testUser查询数据库:

     [Test]
    public void ShouldAddARoleToAUser()
    {
        int userId = -1;
        using (var tx = UserRepository.SessionFactory.OpenSession().BeginTransaction())
        {

            var user = FactoryGirl.GetUser();
            user.AddRole(FactoryGirl.GetRole());

            UserRepository.Create(user);

            tx.Commit();

            UserRepository.SessionFactory.OpenSession().Flush();

            userId = user.Id;
        }

        var testUser = UserRepository.Get(userId);

        Assert.IsNotNull(testUser);
        Assert.IsNotNull(testUser.Roles);
        Assert.IsTrue(testUser.Roles.Count == 1);
        Assert.IsTrue(testUser.Roles[0].Id > 0);

    }

更新II

我的user.cs看起来像:

        private IList<Role> _roles = new List<Role>(); 

        public virtual IList<Role> Roles
        { 
            get { return _roles;  }
        }

        public virtual void AddRole(Role role)
        {
            if(!_roles.Contains(role))
            {
                _roles.Add(role);
            }
        }

Role.cs:

        private IList<User> _users = new List<User>();
        public virtual IList<User> Users
        {
            get { return _users; }
        }

更新III

奇怪这是我的测试通过,但是看看探查器我可以看到它甚至没有命中sql server所以即使我调用Flush,然后做一个Get(userId)它正在加载实体从记忆里。 另外,查看关系(角色)的另一端,Role.Users是{}那么问题是什么?

3 个答案:

答案 0 :(得分:2)

正如小伙子所说,.Inverse()关于关系的声明是UserRole没有被持久化的原因。

取自Nhibernate的引用(这特别针对3.2,但对于NH的早期版本同样存在)http://nhibernate.info/doc/nh/en/index.html#collections-bidirectional 它明确地说:

仅对关联的反向结束所做的更改不会保留

然后更改关联的反向结束User.Roles,当然,不会保留。

因此,您要么更改映射声明,要么更改代码以在关联的非反向端执行保存。如果您有其他代码依赖于User.Roles

上的反向声明,则第一个解决方案可能(或可能不)引入问题 方注意,你说你不知道要清除第一个lvl缓存,相关的调用是:

ISession.Clear()表示缓存上的压路器效果

ISession.Evict(entity),以及特定实体

答案 1 :(得分:1)

如果您正在为集合使用私人支持字段,我认为您必须像这样映射它们:

public class UserMap : ClassMap<User>
{
   public UserMap()
   {
      HasManyToMany(x => x.Roles)
                .Table("RolesUsers")
                .Access.AsCamelCaseField(Prefix.Underscore)
                .ParentKeyColumn("UserId")
                .ChildKeyColumn("RoleId")
                .Cascade.All()
                .Inverse();
   }
}

以上主要差异为.Access.AsCamelCaseField(Prefix.Underscore)

编辑:

除此之外,我认为您需要将测试简化为以下内容:

User newUser = new User();
Role newRole = new Role();
newUser.AddRole(newRole);
newRole.AddUser(newUser);

using (NHibernate.ISession session = iSessionFactory.OpenSession())
{
    using (NHibernate.ITransaction tran = session.BeginTransaction())
    {
        session.Save(newUser);
        tran.Commit();
    }
}

以上可能不准确,但我想你会明白我在说什么。

答案 2 :(得分:0)

验证您是否在事务中执行插入操作。如果没有它,NHibernate将不会在连接表中插入值