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