這次把常用的三種數據關係配置用例子給出,方便以後直接參考。
這次的配置是:SharpDevelop3.0beta, sql server 2k和nhibernate2.0GA版, 測試用的NUnit2.4.7版。
示例下載:
http://download.csdn.net/source/596685
新建一個項目,命名爲Demo3。
加入引用,有NHiberanet.dll和Iesi.Collection.dll,測試用的nunit.framwork.dll。
還是老規則,cs文件放在Domain目錄下,hbm.xml放在Mappings目錄下,因爲這次都是小例子,所以都是全手工寫的,沒有用生成工具,代碼和配置文件都很簡單明瞭。
One-to-One
Person和Passport,代表一個人有一本護照(或者身份證),一對一,呵呵。
- public class Person
- {
- public Person()
- {
- }
- virtual public int ID {get; set;}
- virtual public int Age {get; set;}
- virtual public string Name {get; set;}
- virtual public Passport Passport {get; set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Person">
- <id name="ID">
- <generator class="native"/>
- </id>
- <property name="Age"/>
- <property name="Name"/>
- <one-to-one name="Passport" class="Passport" cascade="all"/>
- </class>
- </hibernate-mapping>
- public class Passport
- {
- public Passport()
- {
- }
- virtual public int ID {get; set;}
- virtual public string Expire {get;set;}
- virtual public Person Person{get;set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Passport">
- <id name="ID">
- <generator class="foreign">
- <param name="property">Person</param>
- </generator>
- </id>
- <property name="Expire"/>
- <one-to-one name="Person" class="Person" constrained="true"/>
- </class>
- </hibernate-mapping>
測試代碼:
- [Test]
- public void TestAdd()
- {
- var person = new Person();
- person.Age = 25;
- person.Name = "abin";
- var passport = new Passport();
- passport.Expire = "never";
- person.Passport = passport;
- passport.Person = person;
- var session = HibernateFacotry.CurrentSession();
- var tran = session.BeginTransaction();
- session.Save(person);
- tran.Commit();
- }
One-to-Many
這個例子更明瞭,Parent和Child,一對多。
- public class Parent
- {
- public Parent()
- {
- }
- virtual public int ID{get;set;}
- virtual public ISet<Child> Children{get;set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Parent">
- <id name="ID">
- <generator class="native"/>
- </id>
- <set name="Children" cascade="all" lazy="true">
- <key column="parent_id"></key>
- <one-to-many class="Child"/>
- </set>
- </class>
- </hibernate-mapping>
- public class Child
- {
- public Child()
- {
- }
- virtual public int ID {get; set;}
- virtual public Parent Parent{get;set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Child">
- <id name="ID">
- <generator class="native"/>
- </id>
- <many-to-one name="Parent" column="parent_id" class="Parent"/>
- </class>
- </hibernate-mapping>
Many-to-Many
這個例子是教科書上的經典,學生選課,Student,Lesson,和student_lesson。但配置中最後一個表是不會出現的,它只是配置表,在數據庫中有,但配置裏面沒有。
- public class Student
- {
- public Student()
- {
- lessons = new HashedSet<Lesson>();
- }
- virtual public int ID{get;set;}
- virtual public ISet<Lesson> lessons{get;set;}
- virtual public int age{get;set;}
- virtual public string name{get;set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Student">
- <id name="ID">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <property name="age"/>
- <set name="lessons" table="student_lesson" lazy="true" inverse="false" cascade="save-update">
- <key column="student_id"></key>
- <many-to-many class="Lesson" column="lesson_id"></many-to-many>
- </set>
- </class>
- </hibernate-mapping>
- public class Lesson
- {
- public Lesson()
- {
- students = new HashedSet<Student>();
- }
- virtual public ISet<Student> students{get;set;}
- virtual public int ID{get;set;}
- virtual public string LessonName{get;set;}
- }
- <?xml version="1.0"?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo3" namespace="Demo3.Domain">
- <class name="Lesson">
- <id name="ID">
- <generator class="native"/>
- </id>
- <property name="LessonName"/>
- <set name="students" table="student_lesson" lazy="true" inverse="true" cascade="save-update">
- <key column="lesson_id"></key>
- <many-to-many class="Student" column="student_id"></many-to-many>
- </set>
- </class>
- </hibernate-mapping>
多對多的配置容易讓人發暈,說明一下。Set裏面的table指定的是配置表,Key裏面的列是指在配置表裏哪一列是可以確認本類的,比如這個例子裏面,本類是Lesson,所以在配置表裏面,lesson_id是用來確認本類數據的,而many-to-many指的是關係那邊的類Student的情況,所以Student對應的列是student_id。另外一邊是一樣的,因爲many2many是對等的。記得Key和many-to-many中的column都要寫,這樣生成的配置表纔會正確。
測試一下
- [Test]
- public void TestMethod()
- {
- // TODO: Add your test.
- var lesson = new Lesson();
- var student = new Student();
- lesson.LessonName = "math";
- lesson.students.Add(student);
- student.age = 14;
- student.name = "afrid";
- student.lessons.Add(lesson);
- var session = HibernateFacotry.CurrentSession();
- var tran = session.BeginTransaction();
- session.Save(student);
- tran.Commit();
- HibernateFacotry.CloseSession();
- }
主控方也要設置一下,主控方是inverse爲false的那方。不設的話NHibernate會生成四條sql,最後一條會重複寫數據,當然就不正確了。