您的位置:首页 > 其它

NHibernate学习笔记(二):one-to-one关系映射

2008-10-25 11:36 381 查看
本文的内容:
1.介绍NH如何处理对象间one-to-ont的映射关系;

经验教训:
1.操作一对一关联关系中的一个对象时,得在程序中指定如何与另一个对象关联,如在Student类中写this.NativePlace.Student = this;
2.在为类写映射文件时,必须指定类的具体的名称空间,若则运行时会出现"找不到***映射文件"的问题;
  这两点都困扰了我好长一段时间,应该要引起注意.

点击下载本文相关代码(可在上篇代码的基础上做修改)
one-to-one:
NH中处理一对一关联的方式有两种:
1.主键关联
2.惟一外键关联

本文使用主键关联处理一对一的关系。

  主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!

  持久化对象之间一对一的关联关系是通过one
-to-one
元素定义的。


<one-to-one


name="propertyName"(1)


class="ClassName"(2)


cascade="all|none|save-update|delete"(3)


constrained="true|false"(4)


outer-join="true|false|auto"(5)


property-ref="propertyNameFromAssociatedClass" (6)


access="field|property|ClassName"(7)


/>



  以下是对one-to-one元素各属性的说明:
  1.name:属性的名字
  2.class:(可选 - 默认是通过反射得到的属性类型): 被关联的类的名字
  3.cascade:(可选) 表明操作是否从父对象级联到被关联的对象
  4.constrained:(可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响
Save()
Delete()
在级联执行时的先后顺序(也在schema export tool中被使用)
  5.outer-join:(可选 - 默认为
auto
):当设置
hibernate.use_outer_join
的时候,对这个关联允许外连接抓取
  6.property-ref:(可选): 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键
  7.access:(可选 - defaults to
property
): NHibernate 用来访问属性的策略

本文所涉及的类说明:


其中BizObject、User、ObjectBroker、Sessions等四个类就是NHibernate学习笔记(一):初识NHibernate这篇文章定义的。
Student类和NativePlace类是一对一的双向关联关系:类Student通过属性NativePlace关联类NativePlace;类NativePlace通过属性Student关联类Student。

类Student的代码如下:


using System;


using System.Collections.Generic;


using System.Text;




namespace NHibernateTest






{


public class Student : User






{




fields#region fields


private NativePlace objNativePlace;


#endregion






constructors#region constructors


public Student()






{


objNativePlace = new NativePlace();


}






public Student(int StudentID) : base(StudentID)

{ }


#endregion






properties#region properties


public NativePlace NativePlace






{


get






{


return objNativePlace;


}


set






{


objNativePlace = value;


}


}


#endregion






methors#region methors


public bool addNewStudent()






{


try






{


this.NativePlace.Student = this;


this.Create();


return true;


}


catch (Exception e)






{


return false;


}


}




public bool deleteStudent()






{


try






{


this.NativePlace.Student = this;


this.Delete();


return true;


}


catch (Exception e)






{


return false;


}


}




public bool updateStudent()






{


try






{


this.NativePlace.Student = this;


this.Update();


return true;


}


catch (Exception e)






{


return false;


}


}


#endregion


}


}



  在每次操作Student对象时,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果没写这一行运行时会出现“could not find class:NativePlace”(我就在写卡了好久)

类NativePlace的代码如下:


using System;


using System.Collections.Generic;


using System.Text;




namespace NHibernateTest






{


public class NativePlace : BizObject






{




fields#region fields


private int intNPID;


private string strCity;


private string strProvince;


private Student objStudent;


#endregion






properties#region properties


public int NPID






{


get






{


return intNPID;


}


set






{


intNPID = value;


}


}




public Student Student






{


get






{


return objStudent;


}


set






{


objStudent = value;


}


}




public string Province






{


get






{


return strProvince;


}


set






{


strProvince = value;


}


}




public string City






{


get






{


return strCity;


}


set






{


strCity = value;


}


}


#endregion


}


}



  这两个类的定义相对于User类没有什么太大的区别,接下来介绍两个类的配置文件。

  从UML来看,类NativePlace与类User之间是集合(构成)关系,即类NativePlace属于类Student的一部分,但不能独立存在,也就是说类NativePlace是依赖于类User的。

数据库脚本:


--表Users:用于保存Student对象


Create Table [Users]


(


[ID] int identity(1,1) constraint PK_UserID1 Primary Key,


[UserName] varchar(20) not null,


[Password] varchar(20) not null


)




--表NativePlace:用于保存NativePlace对象


Create Table NativePlace


(


--表NativePlace与表Users通过主键关联,则需保证两表的主键名一致


ID int Constraint PK_NativePlaceID Primary Key,


Province varchar(50),


City varchar(50)


)
类Student的映射文件:


<?xml version="1.0" encoding="utf-8" ?>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">


<class name="NHibernateTest.Student,NHibernateTest" table="Users">


<id name="UserID" column="ID" type="Int32" unsaved-value="0">


<generator class="identity"/>


</id>


<property name="UserName" column="UserName" type="String" length="20"/>


<property name="Password" column="Password" type="String" length="20"/>




<one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />


</class>


</hibernate-mapping>



类NativePlace的映射文件:


<?xml version="1.0" encoding="utf-8" ?>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">


<class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">


<id name="NPID" column="ID" type="Int32" unsaved-value="0">


<generator class="foreign">


<param name="property">Student</param>


</generator>


</id>


<property name="Province" column="Province" type="String" length="50"/>


<property name="City" column="City" type="String" length="50"/>




<one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>


</class>


</hibernate-mapping>


注意:如果采用<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">这种声明的话,请在之后指写相关联类的名字时请指出完整的类名(名称空间+类名)和程序集名:如<class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">和<one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>

接下来是测试类:



using System;


using System.Collections.Generic;


using System.ComponentModel;


using System.Data;


using System.Drawing;


using System.Text;


using System.Windows.Forms;




namespace NHibernateTest






{


public partial class frmStudent : Form






{


public frmStudent()






{


InitializeComponent();


}




Student objStudent;




//Add New Student


private void button1_Click(object sender, EventArgs e)






{


objStudent = new Student();




objStudent.UserName = "jailu";


objStudent.Password = "123";


objStudent.NativePlace.Province = "FuJian";


objStudent.NativePlace.City = "LongYan";




if (objStudent.addNewStudent())






{


MessageBox.Show("Success");


}


else






{


MessageBox.Show("UnSuccess");


}


}




//Update


private void btnUpdate_Click(object sender, EventArgs e)






{


objStudent.UserName = "Update UserName";


objStudent.NativePlace.Province = "Update Province";




if (objStudent.updateStudent())






{


MessageBox.Show("Success");


}


else






{


MessageBox.Show("UnSuccess");


}


}




//Delete


private void btnDelete_Click(object sender, EventArgs e)






{


if (objStudent.deleteStudent())






{


MessageBox.Show("Success");


}


else






{


MessageBox.Show("UnSuccess");


}


}


}


}
  所有的类和映射文件都写好了,运行...成功.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: