zoukankan      html  css  js  c++  java
  • (转载)一对多关系延迟机制

    准备工作

    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 int Unid { get; set; }

            public virtual int Version { get; set; }

            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">

        <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"></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>

    </class>

     

    场景描述:这是在一对多的关系下。

    (一)使用延迟加载

    默认情况下是延迟加载,可以显示声明为延迟加载:

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

    这时,做为集合的属性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属性已经被填充,集类型为:

    Orders {Domain.Entities.Order}

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

    {NHibernate.Collection.Generic.PersistentGenericBag

    <Domain.Entities.Order>}

    ·Orders属性填充有异常:NHibernate.LazyInitializationException

    测试二:

    接上句执行:

    IList<Order> _list = cc.Orders;

    ·也执行了一条查询

    ·有异常发生,不能加载数据

    在延迟机制下,会话间断时,不能正常加载一对多关系中的多的数据,也就是一对多关系中一的一方的多方集合的属性不能被正常填充。

     

    总结:在应用延迟策略的情况下,在一对多关系的情况下,如果会话间断,会不能正常访问被延迟加载的数据。但在会话期间,应用延迟策略会提高效率。

    (二)使用立即加载

    默认情况下应用延迟加载,通过修改:

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

    来启动立即加载。此时,Customer应用了立即加载,如果它的集合属性(Orders),不设置lazy属性,则集合属性还用默认值,即仍使用延迟加载。所以还要显示的声明Orders集合的lazy属性为不延迟:

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

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

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

    </bag>

    (1)在会话未结束时加载分析

    测试一:

    只执行:

    Customer cc = hh.LoadLazy(38);

    结论:

    ·执行两条查询

    ·Orders属性被填充

     

    测试二:

    接着执行:

    IList<Order> _list = cc.Orders;

    结论:

    ·执行两条查询

    ·Orders属性访问正常

     

    在立即加载机制下,不管是什么情况,只要是申请了一对多关系下一的一方的实例,就会执行两条查询,此时的Oders属性确实已经被填充了。

    (2)会话间断后加载分析

    测试一:

    只执行:

    Customer cc = hh.LoadUseSession(38);

     

    结论:

    ·执行两条查询

    ·Orders被填充,但不会发生异常

     

    测试二:

    接着执行:

    IList<Order> _list = cc.Orders;

    结论:

    ·执行两条查询

    ·Orders被填充

    ·Orders访问正常

     

    结论:

    ·设置立即加载,需要对Bag属性声明lazy=false属性

    ·在立即加载策略下,一对多关系下的数据申请,与会话间断无关,因为数据在会话未间断之前已经被立即加载了。

  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/gracian/p/3680040.html
Copyright © 2011-2022 走看看