首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

NHibernate實戰(9):一對多父子關係映射基石

     編輯:關於.NET

前言

關係映射是 NHibernate 核心亮點亦是難點。本文從集合類型認知入手,構建 Customer-Order 經典一對多父子關係,奠定後續關聯查詢、加載機制探討基礎。

NHibernate 集合類型體系

集合類型特性.NET 對應適用場景
Bag允許重複、無序IList / IList<T>一般列表、允許重複業務
Set唯一、無序ISet / ISet<T> (Iesi.Collections)最貼近關係模型、推薦首選
List有序、允許重複、索引訪問ArrayList / List<T>需保持順序的集合
Map鍵值對Hashtable / IDictionary<TKey,TValue>字典式訪問

實務建議:優先使用 Set,語義最清晰且與資料庫集合論一致。

父子關係建模

Customer(父)1∶N Order(子),資料庫外鍵 Customer 在 Order 表中。

持久化類設計

父端:Customer

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; }
        // 一對多:使用 ISet 保證唯一性
        public virtual ISet<Order> Orders { get; set; }
    }
}

子端:Order

namespace DomainModel.Entities
{
    public class Order
    {
        public virtual int OrderId { get; set; }
        public virtual DateTime OrderDate { get; set; }
        // 多對一:引用父對象
        public virtual Customer Customer { get; set; }
    }
}

映射文件配置詳解

父端映射:Customer.hbm.xml

<class name="DomainModel.Entities.Customer,DomainModel" table="Customer">
    <id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
        <generator class="native" />
    </id>
    <property name="Firstname" column="Firstname" type="string" length="50" />
    <property name="Lastname" column="Lastname" type="string" length="50" />
    
    <!-- 一對多:Set 集合,inverse=true 由子端維護關係 -->
    <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>

關鍵屬性解析

  • inverse="true":關鍵設置!聲明關係由 子端 維護,避免 NHibernate 執行額外 UPDATE 同步外鍵
  • table="`Order`":指定子表名(Order 為保留字需轉義)
  • key column="Customer":子表中外鍵欄位名
  • generic="true":啟用泛型集合

子端映射:Order.hbm.xml

<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" />
    
    <!-- 多對一:指向父端 -->
    <many-to-one name="Customer" column="Customer" not-null="true"
        class="DomainModel.Entities.Customer,DomainModel"
        foreign-key="FK_CustomerOrders" />
</class>

many-to-one 核心屬性速查

屬性默認值說明
cascadenone級聯行為:all/save-update/delete/none
fetchselectselect=單獨查詢、join=外連接抓取
lazyproxyproxy=代理延遲、false=立即加載
not-nullfalse外鍵是否非空
foreign-key-DDL 生成外鍵名稱

雙向導航與關係控制

  • 對象訪問:customer.Orders[...](集合)、order.Customer(單一引用)
  • 關係維護者:inverse="true" 將責任交給 Order 端,插入 Order 時自動設置外鍵
  • 級聯操作:可在 set 或 many-to-one 配置 cascade 控制保存/刪除傳播

結語

一對多映射核心三要素:

  1. 父端使用 Set/Bag + one-to-many + inverse="true"
  2. 子端使用 many-to-one 引用父端
  3. 外鍵欄位位於子表,由子端持久化時維護

掌握此模式,即可構建任意層級的父子關係。下篇將基於此映射展開三大查詢方式實戰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved