今天我们来看一下多对多的关系 Roles <-> Menus ,中间有一个关联表 RoleToMenu 。
它们的关系是 一个角色可以有多个访问菜单,同样一个菜单可能被多个角色使用。多对多关系就出来了
1. 首先处理Roles.cs文件,添加一个属性来存放 Menus 集合
public class Role
{
public virtual int Id { get; set; }
public virtual string R_name { get; set; }
public virtual string R_desc { get; set; }
public virtual IList<Menu> Menus { get; set; }
}
{
public virtual int Id { get; set; }
public virtual string R_name { get; set; }
public virtual string R_desc { get; set; }
public virtual IList<Menu> Menus { get; set; }
}
2. 修改Role.bbm.xml 配置文件
<bag name="Menus" generic="true" table="RoleToMenu" >
<key column="rid" foreign-key="FK_RoleToMenu_Roles"/>
<many-to-many column="mid" class ="llr.Models.Menu,llr.Models" foreign-key="FK_RoleToMenu_Menus"/>
</bag>
<key column="rid" foreign-key="FK_RoleToMenu_Roles"/>
<many-to-many column="mid" class ="llr.Models.Menu,llr.Models" foreign-key="FK_RoleToMenu_Menus"/>
</bag>
<key >标签属性说明 : column 当前配置Role的主键,foreign-key:为关联Roles表的外键名称
<many-to-many >标签属性说明 : column 为Role中关联的Menus表的ID,foreign-key:为关联Menus表的外键名称
3. 修改Menus表,同样也添加存入角色的集合属性
public class Menu
{
public virtual int Id{get;set;}
public virtual string M_title{get;set;}
public virtual int M_parnet{get;set;}
public virtual string M_url { get; set; }
public virtual IList<Role> Roles { get; set; }
}
{
public virtual int Id{get;set;}
public virtual string M_title{get;set;}
public virtual int M_parnet{get;set;}
public virtual string M_url { get; set; }
public virtual IList<Role> Roles { get; set; }
}
4. 修改 Menu.hbm.xml
<bag name="Roles" generic="true" table="RoleToMenu" lazy= "false">
<key column="mid" foreign-key="FK_RoleToMenu_Menus"/>
<many-to-many column="rid" class ="llr.Models.Role,llr.Models"
foreign-key="FK_RoleToMenu_Roles"/>
</bag>
<key column="mid" foreign-key="FK_RoleToMenu_Menus"/>
<many-to-many column="rid" class ="llr.Models.Role,llr.Models"
foreign-key="FK_RoleToMenu_Roles"/>
</bag>
有没有发现跟Role.hbm.xml 差不多呀?同上。只不过把对象主次关系换了一下。
5. 取出数据方法,使用SQL来查询
public static IList<User> GetUserRefInfo()
{
return session.CreateSQLQuery("select distinct u.*,r.*, m.* from Users u"
+ " inner join Roles r on u.r_id=r.rid"
+ " inner join RoleToMenu rm on rm.rid=r.rid"
+ " inner join Menus m on rm.mid=m.mid")
.AddEntity("u", typeof(User)).SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List<User>();
}
{
return session.CreateSQLQuery("select distinct u.*,r.*, m.* from Users u"
+ " inner join Roles r on u.r_id=r.rid"
+ " inner join RoleToMenu rm on rm.rid=r.rid"
+ " inner join Menus m on rm.mid=m.mid")
.AddEntity("u", typeof(User)).SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List<User>();
}
使用HQL也是可以的,但CreateCriteria试过多次没有成功,估计还是配置有问题,这个留下一个悬疑?
6. 显示出来数据
void GetUesrInfo()
{
IList<User> us = UserManager.GetUserRefInfo();
StringBuilder sb = new StringBuilder();
foreach (User u in us)
{
sb.Append("用户:"+u.LogInfo.U_name);
sb.Append("<br/>");
sb.Append("权限:"+u.UserRole.R_name);
foreach (llr.Models.Menu m in u.UserRole.Menus)
{
sb.Append("["+m.M_title+"]");
sb.Append(" ");
}
sb.Append("<br/>");
}
this.Label1.Text = sb.ToString();
}
{
IList<User> us = UserManager.GetUserRefInfo();
StringBuilder sb = new StringBuilder();
foreach (User u in us)
{
sb.Append("用户:"+u.LogInfo.U_name);
sb.Append("<br/>");
sb.Append("权限:"+u.UserRole.R_name);
foreach (llr.Models.Menu m in u.UserRole.Menus)
{
sb.Append("["+m.M_title+"]");
sb.Append(" ");
}
sb.Append("<br/>");
}
this.Label1.Text = sb.ToString();
}
对多对的操作就是这样,下次我们来试试存储过程