Many-To-Many 双向关联
1.双向N——N关联的两边都需要指定连接表的表名,外键列的列名。
2.两个set元素table必须指定,并且必须相同。
3.set元素的两个字元素:key和many-to-many都必须指定column属性,key和many-to-many分别制定本持久化类,关联类在连接表中的外键列名,因此两边的key与many-to-many的column属性交叉相同。
例如:
T_User表
|
|
T_User_Role
|
|
|
T_Role表
|
|||
Id
|
Int主键自增
|
UserId
|
User表id
|
Id
|
Int主键自增
|
|
||
UserName
|
String 50
|
RoleId
|
Role表id
|
RoleName
|
String 50
|
|
||
UserPassword
|
String 50
|
|
|
|
|
|
User类:
―――――――――――――――――――――――――
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace NHibernateTest.Model
{
[Serializable]
public class User
{
private int _userid;
public virtual int UserId
{
get { return _userid; }
set { _userid = value; }
}
private string _username;
public virtual string UserName
{
get { return _username; }
set { _username = value; }
}
private string _userpassword;
public virtual string UserPassword
{
get { return _userpassword; }
set { _userpassword = value; }
}
private IList _roles;
public virtual IList Roles
{
get { return _roles; }
set { _roles = value; }
}
public User()
{
_userid = 0;
_username = null;
_userpassword = null;
_roles = new ArrayList();
}
}
}
Role类:
―――――――――――――――――――――――
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace NHibernateTest.Model
{
[Serializable]
public class Role
{
private int _roleid;
public virtual int RoleId
{
get { return _roleid; }
set { _roleid = value; }
}
private string _rolename;
public virtual string RoleName
{
get { return _rolename; }
set { _rolename = value; }
}
private IList _users;
public virtual IList Users
{
get { return _users; }
set { _users = value; }
}
public Role()
{
_roleid = 0;
_rolename =null;
_users = new ArrayList();
}
}
}
User类映射文件User.hbm.xml:
-----------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="NHibernateTest.Model.User,NHibernateTest.Model"
table="T_User">
<id name="UserId" column="Id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property column="UserName" type="String" name="UserName" not-null="true" length="50" />
<property column="UserPassword" type="String" name="UserPassword" not-null="true" length="50" />
<bag name="Roles" table="T_User_Role" lazy="true">
<!--指定本持久化类(User)在连接表(T_User_Role)中的外键列名UserId,也就是T_User_Role表的UserId -->
<key column="UserId"/>
<!--指定关联类(Role)在连接表(T_User_Role)中的外键列名RoleId -->
<many-to-many class="NHibernateTest.Model.Role,NHibernateTest.Model" column="RoleId"/>
</bag>
</class>
</hibernate-mapping>
Role类映射文件 Role.hbm.xml:
---------------------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="NHibernateTest.Model.Role,NHibernateTest.Model" table="T_Role">
<id name="RoleId" column="Id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property column="RoleName" type="String" name="RoleName" not-null="true" length="50" />
<bag name="Users" table="T_User_Role" lazy="true" inverse="true">
<!--指定本持久化类(Role)在连接表(T_User_Role)中的外键列名,也就是T_User_Role表的RoleId-->
<key column="RoleId"/>
<!--指定关联类(User)在连接表(T_User_Role)中的外键列名-->
<many-to-many class="NHibernateTest.Model.User,NHibernateTest.Model" column="UserId"/>
</bag>
</class>
</hibernate-mapping>
实现代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using NHibernateTest.Model;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
namespace NHibernateTest
{
/* many-to-many和别的关联映射有所不同。
* 例子中:Role和User没有直接的依赖关系,而是通过一张中间表完成。
* 在删除User时一般不会要求删除Role,而是删除之间的关系
* (即从中间表删除数据)。
*/
public partial class Many_To_Many : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void TestAddRoleToUser_Click(object sender, EventArgs e)
{
Configuration config = new Configuration();
config.AddAssembly("NHibernateTest.Model");
ISessionFactory sessions = config.BuildSessionFactory();
ISession session = sessions.OpenSession();
ITransaction trans = session.BeginTransaction();
try
{
User user = session.Load(typeof(User), 4) as User;
Role role = session.Load(typeof(Role), 4) as Role;
user.Roles.Add(role);
role.Users.Add(user);
session.Update(user);
trans.Commit();
}
catch
{
trans.Rollback();
throw new Exception("失败!");
}
finally
{
session.Close();
}
}
//移除user和role的关联关系
protected void TestRemoveRoleFromUser_Click(object sender, EventArgs e)
{
Configuration config = new Configuration();
config.AddAssembly("NHibernateTest.Model");
ISessionFactory sessions = config.BuildSessionFactory();
ISession session = sessions.OpenSession();
ITransaction trans = session.BeginTransaction();
try
{
//移除user和role的关联关系
User user = session.Load(typeof(User), 5) as User;
Role role = session.Load(typeof(Role), 5) as Role;
user.Roles.Remove(role);
role.Users.Remove(user);
session.Update(user);
trans.Commit();
}
catch
{
trans.Rollback();
throw new Exception("失败!");
}
finally
{
session.Close();
}
}
//更新了与UserId=6关联的Role的RoleName名字
protected void TestUpdateUserWithRole_Click(object sender, EventArgs e)
{
Configuration config = new Configuration();
config.AddAssembly("NHibernateTest.Model");
ISessionFactory sessions = config.BuildSessionFactory();
ISession session = sessions.OpenSession();
ITransaction trans = session.BeginTransaction();
try
{
//更新了与UserId=6关联的Role的RoleName名字
User user = session.Load(typeof(User), 6) as User;
((Role)user.Roles[0]).RoleName = "UpdateRole";
session.Update(user);
trans.Commit();
}
catch
{
trans.Rollback();
throw new Exception("失败!");
}
finally
{
session.Close();
}
}
//删除T_User表id=10的记录和删除了T_User_Role表的UserId=10的记录
//跟踪Sql:go
/* DELETE FROM T_User_Role WHERE UserId = @p0', N'@p0 int', @p0 = 10
DELETE FROM T_User WHERE Id = @p0', N'@p0 int', @p0 = 10
*/
protected void TestDeleteUserWithSetRole_Click(object sender, EventArgs e)
{
Configuration config = new Configuration();
config.AddAssembly("NHibernateTest.Model");
ISessionFactory sessions = config.BuildSessionFactory();
ISession session = sessions.OpenSession();
ITransaction trans = session.BeginTransaction();
try
{
User user = session.Load(typeof(User), 10) as User;
session.Delete(user);
trans.Commit();
}
catch
{
trans.Rollback();
throw new Exception("失败!");
}
finally
{
session.Close();
}
}
//添加了User,Role 以及User-Role的关系
protected void TestAddUserAndRole_Click(object sender, EventArgs e)
{
Configuration config = new Configuration();
config.AddAssembly("NHibernateTest.Model");
ISessionFactory sessions = config.BuildSessionFactory();
ISession session = sessions.OpenSession();
ITransaction trans = session.BeginTransaction();
try
{
User user = new User();
user.UserName = "222";
user.UserPassword = "222";
Role role = new Role();
role.RoleName = "秘书";
role.Users.Add(user);
user.Roles.Add(role);
session.Save(user);
session.Save(role);
trans.Commit();
}
catch
{
trans.Rollback();
throw new Exception("失败!");
}
finally
{
session.Close();
}
}
}
}