日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

NHibernate从入门到精通系列(7)——多对一关联映射

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NHibernate从入门到精通系列(7)——多对一关联映射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

  內容摘要

  多對一關聯映射概括

  多對一關聯映射插入和查詢

  多對一關聯映配置介紹

?

  一、多對一關聯映射概括

  關聯關系是實體類與實體類之間的結構關系,分別為“多對一”、“一對一”、“多對多”。然而“多對一”是怎樣描述的呢?讓我們參考圖1.1所示:

 

圖1.1 

?

  學生表“T_Student”有兩條記錄,它們分別對應了班級表“T_Class”的主鍵值為“1”的同一條記錄。所以這就是“多對一”的使用情景。

  讓我們看一下“多對一”持久化類的結構:

  

????public?class?Class
????{
????????
public?virtual?int??ID?{?get;?set;?}

????????
public?virtual?string?Name?{?get;?set;?}
????}

????
public?class?Student
????{
????????
public?virtual?int??ID?{?get;?set;?}

????????
public?virtual?string?Name?{?get;?set;?}

????????
public?virtual?Class?Class?{?get;?set;?}
????}

?

  在“Student”類中有類型為“Class”的屬性,這就意味著在“Student”有一個與之對應的“Class”類。

  再讓我們看一下映射文件:

?

<class?name="Class"?table="T_Class"?lazy="true"?>
????
<id?name="ID"?type="int"?column="ClassID">
??????
<generator?class="native"/>
????
</id>
??
????
<property?name="Name"?type="string">
??????
<column?name="Name"?length="50"/>
????
</property>

??
</class>

??
<class?name="Student"?table="T_Student"?lazy="true"?>
????
<id?name="ID"?type="int"?column="StudentID">
??????
<generator?class="native"/>
????
</id>
??
????
<property?name="Name"?type="string">
??????
<column?name="Name"?length="50"/>
????
</property>

????
<many-to-one?name="Class"?column="ClassID"/>
????
??
</class>

?

  我在“Student”類的映射文件中發現了“many-to-one”節點,<many-to-one>標簽是描述“多對一”的關聯映射。

  該標簽的name屬性是“多對一”的類名,column是外鍵字段名。

  我們配置好映射文件后運行程序,生成的表結構如圖1.2所示:

圖1.2

?

  發現NHibernate幫我們生成了一個外鍵。

?

  二、多對一關聯映射插入和查詢

  2.1 多對一關聯映射插入

  我們編寫一個測試類,測試一下“多對一”關聯映射的插入。

?  代碼如下:

?

?[TestFixture]
????
public?class?NHibernateInit
????{
????????
private?ISessionFactory?sessionFactory;

????????[SetUp]
????????
public?void?InitTest()
????????{
????????????var?cfg?
=?new?NHibernate.Cfg.Configuration().Configure("Config/hibernate.cfg.xml");
????????????sessionFactory?
=?cfg.BuildSessionFactory();
????????}

????????[Test]
????????
public?void?Save()
????????{
????????????
using?(ISession?session?=?this.sessionFactory.OpenSession())
????????????{
????????????????var?cls?
=?new?Class?{?Name?=?"1班"?};

????????????????var?liu?
=?new?Student?{?Name?=?"劉冬",?Class?=?cls?};
????????????????var?zhang?
=?new?Student?{?Name?=?"張三",?Class?=?cls?};

????????????????ITransaction?tran?
=?session.BeginTransaction();
????????????????
try
????????????????{
????????????????????session.Save(liu);
????????????????????session.Save(zhang);

????????????????????tran.Commit();
????????????????}
????????????????
catch(Exception?ex)?
????????????????{
????????????????????tran.Rollback();
????????????????????
throw?ex;
????????????????}
????????????}
????????}
????}

?

  使用NUnit運行測試類。如圖2.1.1所示,發現拋出“object references an unsaved transient instance - save the transient instance before flushing. Type: Domain.Class, Entity: Domain.Class”這樣的異常。

圖2.1.1

?

  這個異常是怎么回事呢?持久化“Student”類的實例后,“Student”類的實例變為“持久態(Persistent)”,而“Class”類的實例還是臨時態(Transient),當持久化一個持久態的實例時,若該實例引用了一個臨時態的實例,就會拋出這樣的異常。

  我們修改一下代碼:

  

[Test]
????????
public?void?Save()
????????{
????????????
using?(ISession?session?=?this.sessionFactory.OpenSession())
????????????{
????????????????var?cls?
=?new?Class?{?Name?=?"1班"?};

????????????????var?liu?
=?new?Student?{?Name?=?"劉冬",?Class?=?cls?};
????????????????var?zhang?
=?new?Student?{?Name?=?"張三",?Class?=?cls?};

????????????????ITransaction?tran?
=?session.BeginTransaction();
????????????????
try
????????????????{
????????????????????
//持久化“Class”類
????????????????????session.Save(cls);

????????????????????session.Save(liu);
????????????????????session.Save(zhang);

????????????????????tran.Commit();
????????????????}
????????????????
catch(Exception?ex)?
????????????????{
????????????????????tran.Rollback();
????????????????????
throw?ex;
????????????????}
????????????}
????????}

?

?  然后運行修改過的程序。如圖2.1.2所示,運行成功。

圖2.1.2

  同理,我們也可以修改<many-to-one>標簽中的cascade屬性為“all”,這樣就能實現同樣的效果。設置cascade屬性后,當持久態的實例引用臨時態的實例時,NHibernate就會幫我們把這個臨時態的實例自動持久化到數據庫中。

?

  2.2 多對一關聯映射查詢

  我們編寫一個查詢方法,當獲取到“Student”時,可以通過其“Class”屬性讀取“Class”的信息。

?

??????? [Test]
????????
public?void?Select()
????????{
????????????
using?(ISession?session?=?this.sessionFactory.OpenSession())
????????????{
????????????????var?student?
=?session.CreateQuery("?from?Student").List<Student>().First();

????????????????Console.WriteLine(
"學生名為:{0}",?student.Name);

????????????????Console.WriteLine(
"班級名為:{0}",?student.Class.Name);
????????????}
????????}

?

  

  運行效果如圖2.2.1所示,我們并沒有再去調用查詢方法,就能獲取到關聯的信息。

圖2.2.1

?

  

  三、多對一關聯映配置介紹

  <many-to-onename="PropertyName"                                屬性名column="column_name"                               數據庫字段名class="ClassName"                                  關聯的類的名字cascade="all|none|save-update|delete"              級聯關系fetch="join|select"                                抓取update="true|false"                                insert="true|false"                                property-ref="PropertyNameFromAssociatedClass"     指定關聯類的一個屬性,這個屬性將會和本外鍵相對應access="field|property|nosetter|ClassName"         unique="true|false"                                是否生成一個唯一約束optimistic-lock="true|false"                       not-found="ignore|exception"                       指定外鍵引用的數據不存在時如何處理/>

?

  代碼下載

  出處:http://www.cnblogs.com/GoodHelper/archive/2011/02/24/nhibernate07.html

  歡迎轉載,但需保留版權。

轉載于:https://www.cnblogs.com/GoodHelper/archive/2011/02/24/nhibernate07.html

總結

以上是生活随笔為你收集整理的NHibernate从入门到精通系列(7)——多对一关联映射的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。