天天看點

NHibernate初探(七) 一對多關系延遲機制

準備工作

Customer

public class Customer

    {

        public virtual int Unid { get; set; }

        public virtual DateTime CreateTime { get; set; }

        public virtual string Address { get; set; }

        public virtual int Version { get; set; }

        private IList<Order> _orderList = new List<Order>();

        public virtual IList<Order> Orders

 { get { return _orderList; } set { _orderList = value; } }

}

Order

public class Order

        public virtual DateTime? CreateTime { get; set; }

        public virtual Customer Customer { get; set; }

        public virtual string Memo { get; set; }     

Customer mapping

<class name="Customer" table="Customer" lazy="true">

    <id name="Unid" column="Unid">

      <generator class="identity"></generator>

    </id>

    <version name="Version" column="Version" type="integer" unsaved-value="0"></version> 

    <property name="CreateTime" column="CreateTime" insert="false" update="false"></property>

    <property name="Address" column="Address"></property>

    <bag name="Orders" table="POrder" cascade="all" inverse="true" lazy="false">

      <key column="CustomerId"></key>

      <one-to-many class="Domain.Entities.Order,Domain"/>

    </bag>

</class>

Order mapping

<class name="Order" table="POrder">

    <version name="Version" column="Version" type="integer" unsaved-value="0"></version>

    <property name="CreateTime" column="CreateTime"></property>

     <property name="Memo" column="Memo"></property>

   <many-to-one name="Customer" column="CustomerId"

 class="Domain.Entities.Customer,Domain" not-null="true"></many-to-one>

場景描述:這是在一對多的關系下。

(一)使用延遲加載

預設情況下是延遲加載,可以顯示聲明為延遲加載:

這時,做為集合的屬性Orders映射應該預設也是延遲(待證),是以bag的lazy屬性也是true

(1)在會話未結束時加載分析

方法LoadLazy(),用于在會話間延遲加載

ISession _Session = NHBSessionFactory.GetSession;

public Customer LoadLazy(int iUnid)

{

_Session = NHBSessionFactory.GetSession;

return _Session.Get<Customer>(iUnid);

測試一:

Customer cc = hh.LoadLazy(38);

隻執行這步。

結論:

·執行一句查詢

·此時,Orders屬性已經被填充,集類型為:

Orders  {Domain.Entities.Order}

System.Collections.Generic.IList<Domain.Entities.Order>

{NHibernate.Collection.Generic.PersistentGenericBag

<Domain.Entities.Order>}

測試二:

接上句,執行:

IList<Order> _list = cc.Orders;

·執行兩條查詢

·Orders屬性已經被填充,集類型同上

在未結束的本次會話中,延遲加載會正常進行;而且當延遲加載時,如果不需要被延遲的部分(Orders屬性),那麼效率會高些。

(2)會話結束後的延遲加載

public Customer LoadUseSession(int iUnid)

        {

            using (_Session)

            {

                Customer cc=_Session.Get<Customer>(iUnid);

                return cc;

            }

        }

Customer cc = hh.LoadUseSession(38);

隻執行到這步。

·執行一條查詢

Orders {Domain.Entities.Order}

·Orders屬性填充有異常:NHibernate.LazyInitializationException

接上句執行:

·也執行了一條查詢

·有異常發生,不能加載資料

在延遲機制下,會話間斷時,不能正常加載一對多關系中的多的資料,也就是一對多關系中一的一方的多方集合的屬性不能被正常填充。

總結:在應用延遲政策的情況下,在一對多關系的情況下,如果會話間斷,會不能正常通路被延遲加載的資料。但在會話期間,應用延遲政策會提高效率。

(二)使用立即加載

預設情況下應用延遲加載,通過修改:

<class name="Customer" table="Customer" lazy="false">

來啟動立即加載。此時,Customer應用了立即加載,如果它的集合屬性(Orders),不設定lazy屬性,則集合屬性還用預設值,即仍使用延遲加載。是以還要顯示的聲明Orders集合的lazy屬性為不延遲:

<bag name="Orders" table="POrder" cascade="all" inverse="true" lazy="false">

</bag>

隻執行:

·Orders屬性被填充

接着執行:

·Orders屬性通路正常

在立即加載機制下,不管是什麼情況,隻要是申請了一對多關系下一的一方的執行個體,就會執行兩條查詢,此時的Oders屬性确實已經被填充了。

(2)會話間斷後加載分析

·Orders被填充,但不會發生異常

·Orders被填充

·Orders通路正常

·設定立即加載,需要對Bag屬性聲明lazy=false屬性

·在立即加載政策下,一對多關系下的資料申請,與會話間斷無關,因為資料在會話未間斷之前已經被立即加載了。

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園

繼續閱讀