代码
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(); } } }}One-To-Many(单项关联1-N)因为集合属性都需要保存到另一个数据表中,所以保存集合属性表必须必须包含一个外键列,用于参照主键列。该外键列通过在 < Set /> 等集合元素中使用 < key… /> 子元素column来映射。不管使用那种集合,使用 < bag.. /> 元素都将映射成无序集合。集合属性对应的表没有主键。对于1—N的单向关联,需要在1的一端增加对应的集合映射元素。与映射集合类似,必须为 < set > , < bag > 等集合元素增加key子元素,用以映射关联外键列。one - to - many标签包含在标签bag / set中.bag标签的。inverse属性使collection不更新连接。key标签的column属性指出了在另一个数据库表中加入外键,来关联本类。T_Parent T_ChildId Int主键自增 ChildId Int自增Name String Name String ParentId T_Parent表IdMany-To-Onemany - to - one:描述多对一的一种数据模型,它指定many一方是不能独立存在的,我个人认为many - to - one是NHB中保证数据有效性的最有用的一种映射,通过使用many - to - one能有效的防治孤儿记录被写入到数据表中。 < many - to - one name = " propertyName " ( 1 ) column = " column_name " ( 2 ) class = " ClassName " ( 3 ) cascade = " all|none|save-update|delete " ( 4 ) unique = " true|false " ( 10 ) /> 1 .name:属性名。指出many一方的类用哪个属性和one一方的类关联. 2 .column:字段名(可选).指出many一方的类对应的数据表用哪个列和one一方的类对应的数据表关联(两表之间存在外键关联); 3 . class :关联的类的名字(可选 - 默认是通过反射得到属性类型); 4 .cascade:指明哪些操作会从父对象级联到关联的对象(可选).cascade属性允许下列值:: all, save - update, delete, none. 设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。 5 .unique:允许产生外键列唯一约束的数据库定义语言(DDL)(可选)