to-many中many的一方進行設置(當然,在many一方,可能是在<set>也可能是在<bag>也可能是在<array>中進行設置),而對於one方,是不進行Inverse設置的。在Hibernate社區,inverse默認值為false。
本節班級(Class類)與學生(Student)、學生(Student)與課程(Course)來進行說明。
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int Gender { get; set; }
public virtual Class Class { get; set; }
//public virtual int ClassId { get; set; }
public virtual IList<Course> Courses { get; set; }
}
配置(基本部分,不含many-to-one配置。因為各種測試下inverse\cascade值可能不同,所以具體將在各種測試中給出):
<hibernate-mapping xmlns= " urn:nhibernate-mapping-2.2 ">
< class name= " NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse " lazy= " true " table= " Student ">
<id column= " Id " name= " Id " type= " Int32 ">
<generator class= " native "></generator>
</id>
<property name= " Name " column= " Name "></property>
<property name= " Gender " column= " Gender "></property>
<!--<property name= " ClassId " column= " ClassId "></property>-->
</ class>
</hibernate-mapping>
{
public virtual int Id { get; set; }
public virtual string SerialNO { get; set; }
public virtual int DepartmentId { get; set; }
public virtual ISet<Student> Students { get; set; }
}
<hibernate-mapping xmlns= " urn:nhibernate-mapping-2.2 ">
< class name= " NHibernateCascadeInverse.Entities.Class,NHibernateCascadeInverse ">
<id name= " Id " >
<generator class= " native "></generator>
</id>
<property column= " SerialNO " name= " SerialNO " type= " string "></property>
<property column= " DepartmentId " name= " DepartmentId " type= " Int32 "></property>
</ class>
</hibernate-mapping>
測試1:希望在添加班級時,將若干新學生到該班級中。(注意:在此次測試中,刪除了Class表與Student表之間的主外鍵關系。正常為保證數據的完整性還是應建立主外鍵關系)
class="NHibernateCascadeInverse.Entities.Class,NHibernateCascadeInverse" >
<column name="ClassId" not-null="false" sql-type="int"></column>
</many-to-one>
<key column="ClassId" ></key>
<one-to-many class="NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse"/>
</set>
publicvoid ClassAddTest()
{
Class classEntity = new Class
{
SerialNO = "C0302",
DepartmentId = 36,
Students =
new HashedSet<Student> {new Student {Name = "zhangsan"}, new Student {Name = "zhangsan1"}}
};
var repository = new ClassRepository();
repository.Add(classEntity);
}

據插入的Class對象的ClassId將剛插入的Student進行批量更新。
<key column="ClassId" ></key>
<one-to-many class="NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse"/>
</set>
class= " NHibernateCascadeInverse.Entities.Class,NHibernateCascadeInverse " >
<column name= " ClassId " not- null= " false " sql-type= " int "></column>
</many-to-one>
測試2 結果:

通過以上信息可知:數據被正常保存了,插入數據時,已經為待插入的Student對象構造
好了外鍵。所以在one-to-many關聯中一般通過將many一方(如上例中的Student)作為維護雙方關系
的主控方,也就是在one(如上例中的Class)設置inverse="true"
個學生對應多門課程,一門課程也對應許多學生。
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int TeacherId { get; set; }
public virtual IList<Student> Students { get; set; }
}
Course的映射:(many-to-many部分沒有給出,在各種測試中進行不同配置)
< class name= " NHibernateCascadeInverse.Entities.Course,NHibernateCascadeInverse " lazy= " true " >
<id column= " Id " name= " Id " type= " Int32 ">
<generator class= " native "></generator>
</id>
<property name= " Name " column= " Name "></property>
<property name= " TeacherId " column= " teacherID "></property>
</ class>
</hibernate-mapping>
< class name= " NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse " lazy= " true " table= " Student ">
<id column= " Id " name= " Id " type= " Int32 ">
<generator class= " native "></generator>
</id>
<property name= " Name " column= " Name "></property>
<property name= " Gender " column= " Gender "></property>
<many-to-one name= " Class "
class= " NHibernateCascadeInverse.Entities.Class,NHibernateCascadeInverse " >
<column name= " ClassId " not- null= " false " sql-type= " int "></column>
</many-to-one>
<property name= " ClassId " column= " ClassId "></property>
</ class>
</hibernate-mapping>
設置Student為主控方,即Course的Inverse設置為true.Student many-to-many映射
<key foreign-key= " FK_CourseInfo_Student " column= " StudentId "></key>
<many-to-many class= " NHibernateCascadeInverse.Entities.Course,NHibernateCascadeInverse " column= " CourseId "></many-to-many>
</bag>
Course many-to-many映射
<key foreign-key= " FK_CourseInfo_Course " column= " CourseId ">
</key>
<many-to-many column= " StudentID " class= " NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse "></many-to-many>
</bag>
publicvoid ManyToMany_Test()
{
var student = new Student { Gender = 1, Name = "testAccount", ClassId = 10 };
var course = new Course { Name = "Computer", TeacherId = 1 };
student.Courses = new List<Course> { course };
course.Students = new List<Student> { student };
StudentRepository studentRepository = new StudentRepository();
CourseRepository courseRepository = new CourseRepository();
//courseRepository.Add(course);
studentRepository.Add(student);
}
測試3 結果:

測試三中,以Student為主控方,保存信息的時候也以Student進行保存。倘若以Course一方進行保存,
數據也能正常寫入嗎?
測試4: 以受控方(Course )測試保存many-to-many的數據
publicvoid ManyToMany_Test()
{
var student = new Student { Gender = 1, Name = "testAccount", ClassId = 10 };
var course = new Course { Name = "Computer", TeacherId = 1 };
student.Courses = new List<Course> { course };
course.Students = new List<Student> { student };
CourseRepository courseRepository = new CourseRepository();
courseRepository.Add(course);
}
測試4結果:

由測試三、測試四可以看出:兩種情況下就Student與Course表的寫入順序不一樣,但都能保存正常。所以在many-to-many中,以哪方作為主控方,沒有影響。
設置對象關聯關系中的級聯操作。以上用了cascade="all"。其實它還有其他值:
先通過一個測試簡單了解cascade 的作用。
<key column= " ClassId " ></key>
<one-to-many class= " NHibernateCascadeInverse.Entities.Student,NHibernateCascadeInverse "/>
</ set>
Student的配置還如測試一,保持不變。
測試5 結果如下:

還以Class與Student為例進行刪除測試。
測試准備:通過測試1,添加一個班級、兩條學生信息。
測試:將刪除班級中一條學生信息,然后刪除班級
測試代碼:
public void DeleteClassTest()
{
var repository = new ClassRepository();
Class @class = repository.Get( 287);
IEnumerator<Student> students = @class.Students.GetEnumerator();
Student student = null;
if (students.MoveNext())
{
student = students.Current;
}
if ( null!=student)
{
@class.Students.Remove(student);
}
repository.Delete(@class); }
測試6 結果:

測試代碼同測試六。測試7 結果如下:

由測試六、測試七可知:對於刪除與父類之間的關系時,all-delete-orphan會將孤兒刪除
(orphan意為:孤兒),而all不會刪除,而是將與父關聯的外鍵字段設置為null。