Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 映射用户、角色和角色权限_C#_Nhibernate_Fluent Nhibernate - Fatal编程技术网

C# 映射用户、角色和角色权限

C# 映射用户、角色和角色权限,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我拥有以下实体: User Role 然后是联接表: UsersRoles (UserId, RoleId) 然后是角色权限表: RolePermissions(Id, RoleId, ....) 因此,对于我希望能够做到的用户实体: user.Roles user.RolePermissions 我的UserMap看起来像: public class UserMap : ClassMap<User> { public UserMap() { Has

我拥有以下实体:

User
Role
然后是联接表:

UsersRoles (UserId, RoleId)
然后是角色权限表:

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();
   }

}
        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);
            }
        }
它保存用户,并保存角色,但不插入RolesUsers表?

另外,如何添加属性以获取用户的所有角色权限?

更新

我的角色地图有:

 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);

    }
更新二

My user.cs看起来像:

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

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

}
        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);
            }
        }
private IList_roles=new List();
公共虚拟IList角色
{ 
获取{return\u roles;}
}
公共虚拟void AddRole(角色角色)
{
如果(!\u角色。包含(角色))
{
_角色。添加(角色);
}
}
Role.cs:

        private IList<User> _users = new List<User>();
        public virtual IList<User> Users
        {
            get { return _users; }
        }
private IList_users=new List();
公共虚拟IList用户
{
获取{return\u users;}
}
更新三


奇怪的是,这是我的测试通过了,但查看profiler,我可以看到它甚至没有命中sql server,所以即使我调用Flush,然后执行Get(userId),它也在从内存加载实体另外,查看关系的另一端(Role),Role.Users是{},这就是问题所在吗?

验证您是否正在执行插入事务。NHibernate不会在联接表中插入值,如果没有它,请验证您是否正在事务中插入值。NHibernate不会在没有它的联接表中插入值

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

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

以上可能不准确,但我想你已经明白我在说什么了

如果您的收藏使用私有备份字段,我认为您必须这样映射它们:

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

以上可能不准确,但我想你已经明白我在说什么了

正如brook所建议的,关系上的
.Inverse()
声明是用户角色未持久化的原因

摘自Nhibernate的参考资料(这是3.2的特殊要求,但NH的早期版本也有相同的要求) 它明确地说:

“仅对关联的反向端所做的更改不会持久化”

您可以更改关联的反向端,
User.Roles
,当然,它不会持久化

因此,您可以更改映射声明或代码,以便在关联的非反向端执行保存。如果您有其他依赖于
User.Roles上的反向声明的代码,则第一种解决方案可能会(也可能不会)引入问题

请注意,您说您不知道如何清除第1级缓存,相关调用如下:

ISession.Clear()
用于缓存上的蒸汽辊效果


ISession.execute(entity)
对于特定的实体

,正如brook所建议的那样,关系上的
.Inverse()
声明是用户角色未持久化的原因

摘自Nhibernate的参考资料(这是3.2的特殊要求,但NH的早期版本也有相同的要求) 它明确地说:

“仅对关联的反向端所做的更改不会持久化”

您可以更改关联的反向端,
User.Roles
,当然,它不会持久化

因此,您可以更改映射声明或代码,以便在关联的非反向端执行保存。如果您有其他依赖于
User.Roles上的反向声明的代码,则第一种解决方案可能会(也可能不会)引入问题

请注意,您说您不知道如何清除第1级缓存,相关调用如下:

ISession.Clear()
用于缓存上的蒸汽辊效果


ISession.execute(entity)
对于特定的实体

当你说
Inverse
时,你是在告诉NH关系的另一方(在本例中是角色)负责保存。请发布您的角色映射。@Brook我在上面添加了角色映射。我真的认为您只是想从UserMap中删除.Inverse()。如果你在做Role.Users.Add(user),我认为它会很好。当你说
Inverse
时,你是在告诉NH关系的另一方(在本例中是Role)负责保存。请发布您的角色映射。@Brook我在上面添加了角色映射。我真的认为您只是想从UserMap中删除.Inverse()。如果您正在执行Role.Users.Add(user),我认为它可以正常工作。奇怪的是,它仍然没有保存到RolesUsers表UserRepository到底是什么。Create在做什么?它是否使用与您正在为其创建事务的会话相同的会话?FactoryDb.GetUser()是否正在使用会话?那么FactoryDb.GetRole()呢?这里有很多我们看不到的代码。这可能有助于简化您的测试。在这个测试中,我真的不确定你到底想测试什么。如果你只是想测试你的映射,我会把所有的存储库都排除在外,直接使用NH。存储库都使用同一个会话,在测试案例中是针对当前线程的(thread_static),在web端是针对每个请求的。UserMap.cs端的parentkeycolumn与RoleMap.cs端的parentkeycolumn不同吗?或者两者应该相同。是的,它们是不同的。角色端的父键列是RoleId.奇怪的是,它仍然没有保存到RolesUsers表UserRepository到底是什么。Create在做什么?它是否使用与您正在为其创建事务的会话相同的会话?FactoryDb.GetUser()是否正在使用会话?那么FactoryDb.GetRole()呢?有很多代码t