準備工作
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/轉載請注明:部落格園