[轉]NHibernate之旅(9):探索父子關係(一對多關聯性)

來源:互聯網
上載者:User

標籤:style   blog   http   io   os   使用   ar   strong   for   

本節內容

  • 引入
  • NHibernate中的集合類型
  • 建立父子關係
  • 父子關聯映射
  • 結語
引入

通過前幾篇文章的介紹,基本上瞭解了NHibernate,但是在NHibernate中映射關係是NHibernate中的亮點,也是最難掌握的技術。從這篇開始學習這些東西,我將圖文結合來說明這裡奧秘的知識。

前幾篇,我們的例子只使用了一個簡單的Customer對象。但是在客戶/訂單/產品的經典組合中,他們的關係非常複雜?讓我們先回顧在第二篇中建立的資料模型。

在圖上,我已經清晰的標註了表之間的關係,首先分析Customer和Order之間的“外鍵關係”或者稱作“父子關係”、“一對多關聯性”。在分析之前先初步瞭解NHibernate中的集合。

NHibernate中的集合類型

NHibernate支援/定義的幾種類型的集合:

Bag:對象集合,每個元素可以重複。例如{1,2,2,6,0,0},在.Net中相當於IList或者IList<T>實現。

Set:對象集合,每個元素必須唯一。例如{1,2,5,6},在.Net中相當於ISet或者ISet<T>實現,Iesi.Collections.dll程式集提供ISet集合。

List:整數索引對象集合,每個元素可以重複。例如{{1,"YJingLee"},{2,"CnBlogs"},{3,"LiYongJing"}},在.Net中相當於ArraryList或者List<T>實現。

Map:索引值對集合。例如{{"YJingLee",5},{"CnBlogs",7},{"LiYongJing",6}},在.Net中相當於HashTable或者IDictionary<Tkey,TValue>實現。

實際上,我們大多數情況下使用Set集合類型,因為這個類型和關係型資料庫模型比較接近。

建立父子關係

直接看下面一幅圖的兩張表:

上面兩張表關係表達的意思是:Customer有一個或多個Orders,Orders屬於一個Customer。一般而言,我們稱Customer為“父”,Order稱為“子”。Customer和Order之間關係就有幾種說法:“外鍵關係”、“父子關係”、“一對多關聯性”都可以。

1.Customer有一個或多個Orders

在物件模型中:在Customer類中把Orders作為一個集合,這時可以說Customer對象包含了Orders集合。在.NET中通常這樣表述:

public class Customer{    //......    public IList<Order> Orders{ get; set; }}

訪問對象方式:通過子集合訪問:Customer.Orders[...]

在NHibernate中,通常而言使用Iesi.Collections.dll程式集中的ISet集合,現在修改Customer.cs類,首先需要引用這個程式集,Customer.cs類代碼如下:

using Iesi.Collections.Generic;namespace DomainModel.Entities{    public class Customer    {        public virtual int CustomerId { get; set; }        public virtual string Firstname { get; set; }        public virtual string Lastname { get; set; }        //一對多關聯性:Customer有一個或多個Orders        public virtual ISet<Order> Orders { get; set; }    }}
2.Order屬於一個Customer

在物件模型中:在Order類中把Customer作為單一對象,這時可以說Order對象包含了一個Customer。在.NET中通常這樣表述:

public class Order{    //......    public Customer Customer{ get; set; }}

其訪問對象方式:通過父物件成員訪問:Order.Customer

我們在項目DomainModel層的Entities檔案夾中建立Order.cs類,編寫代碼如下:

namespace DomainModel.Entities{    public class Order    {        public virtual int OrderId { get; set; }        public virtual DateTime OrderDate { get; set; }        //多對一關聯性:Orders屬於一個Customer        public virtual Customer Customer { get; set; }    }}

好了,我們現在完成持久類了,下面看看這兩個類如何映射。

父子關聯映射

在NHibernate中,我們可以通過對應檔來關聯對象之間的關係。對應檔定義了:

  • 對象之間關係:一對一、一對多、多對一、多對多關係。
  • 在關係中控制級聯行為(Cascade behavior):串聯更新、串聯刪除
  • 父子之間的雙嚮導航(bidirectional navigation)
1.父實體映射

父實體(Customer)映射定義了:

  • 集合類型(Bag、Set、List、Map)
  • 在儲存、更新、刪除操作時的級聯行為
  • 關聯的控制方向:
    • Inverse="false"(預設):父實體負責維護關聯關係
    • Inverse="true":子實體負責維護關聯關係
  • 與子實體關聯的關係(一對多、多對一、多對多)

這些具體的設定是NHibernate中的痛點所在,以後慢慢討論這些不同設定下的奧秘之處。

這一篇初步建立Customer與Order的一對多關聯性,修改Customer.hbm.xml對應檔如下:

<?xml version="1.0" encoding="utf-8" ?><hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                    assembly="DomainModel" namespace="DomainModel">  <class name ="DomainModel.Entities.Customer,DomainModel"         table="Customer">    <id name="CustomerId" column="CustomerId" type="Int32"         unsaved-value="0">      <generator class ="native"></generator>    </id>    <property name="Firstname" column ="Firstname" type="string"              length="50" not-null="false"/>    <property name ="Lastname" column="Lastname" type="string"              length="50" not-null="false"/>    <!--一對多關聯性:Customer有一個或多個Orders-->    <set name="Orders" table="`Order`" generic="true" inverse="true">          <key column="Customer" foreign-key="FK_CustomerOrders"/>          <one-to-many class="DomainModel.Entities.Order,DomainModel"/>    </set>  </class></hibernate-mapping>

可以看到,在“父”端映射使用Set元素,標明屬性名稱、表名、子實體負責維護關聯關係。

2.子實體映射

子實體(Order)映射定義的東西就是父實體少了:與父實體關聯的(多對一、一對多、多對多) 關係,並用一個指標來導航到父實體。

在“子”端通過many-to-one元素定義與“父”端的關聯,從“子”端角度看這種關聯式模式是多對一關聯(實際上是對Customer對象的引用)。下面看看many-to-one元素映射屬性:

看看這些映射屬性具體有什麼意義:

  • access(預設property):可選field、property、nosetter、ClassName值。NHibernate訪問屬性的策略。
  • cascade(可選):指明哪些操作會從父物件級聯到關聯的對象。可選all、save-update、delete、none值。除none之外其它將使指定的操作延伸到關聯的(子)對象。
  • class(預設通過反射得到屬性類型):關聯類別的名字。
  • column(預設屬性名):列名。
  • fetch(預設select):可選select和join值,select:用單獨的查詢抓取關聯;join:總是用外串連抓取關聯。
  • foreign-key:外鍵名稱,使用SchemaExport工具產生的名稱。
  • index:......
  • update,insert(預設true):指定對應的欄位是否包含在用於UPDATE或INSERT 的SQL語句中。如果二者都是false,則這是一個純粹的 “外源性(derived)”關聯,它的值是通過映射到同一個(或多個)欄位的某些其他特性得到或者通過觸發器其他程式得到。
  • lazy:可選false和proxy值。是否延遲,不延遲還是使用代理延遲。
  • name:屬性名稱propertyName。
  • not-found:可選ignore和exception值。找不到忽略或者拋出異常。
  • not-null:可選true和false值。
  • outer-join:可選auto、true、false值。
  • property-ref(可選):指定關聯類別的一個屬性名稱,這個屬性會和外鍵相對應。如果沒有指定,會使用對方關聯類別的主鍵。這個屬性通常在遺留的資料庫系統使用,可能有外鍵指向對方關聯表的某個非主鍵欄位(但是應該是一個唯一關鍵字)的情況下,是非常不好的關聯式模式。比如說,假設Customer類有唯一的CustomerId,它並不是主鍵。這一點在NHibernate源碼中有了充分的體驗。
  • unique:可選true和false值。控制NHibernate通過SchemaExport工具產生DDL的過程。
  • unique-key(可選):使用DDL為外鍵欄位產生一個唯一約束。

我們來建立“子”端到“父”端的映射,建立Order.hbm.xml檔案,編寫代碼如下:

<?xml version="1.0" encoding="utf-8" ?><hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                    assembly="DomainModel" namespace="DomainModel">    <class name="DomainModel.Entities.Order,DomainModel" table="`Order`" >    <id name="OrderId" column="OrderId" type="Int32" unsaved-value="0">      <generator class="native" />    </id>    <property name="OrderDate" column="OrderDate" type="DateTime"              not-null="true" />    <!--多對一關聯性:Orders屬於一個Customer-->    <many-to-one name="Customer" column="Customer" not-null="true"                 class="DomainModel.Entities.Customer,DomainModel"                 foreign-key="FK_CustomerOrders" />  </class></hibernate-mapping>

關於如何關聯看看上面的屬性就一目瞭然了。

[轉]NHibernate之旅(9):探索父子關係(一對多關聯性)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.