NHibernate初探(七) 一对多关系延迟机制

简介: 准备工作  Customer public class Customer     {         public virtual int Unid { get; set; }         public virtual DateTime CreateTime { get; set; }...

准备工作

 

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映射应该默认也是延迟(待证),所以baglazy属性也是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属性

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

 

博客园大道至简

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

转载请注明:博客园

目录
相关文章
|
4月前
|
设计模式 数据建模 测试技术
领域模型问题之领域模式多对多关联如何解决
领域模型问题之领域模式多对多关联如何解决
|
6月前
|
SQL XML Java
Hibernate - 单向多对一关联关系映射
Hibernate - 单向多对一关联关系映射
39 0
|
6月前
|
SQL 缓存 Java
Hibernae - 双向多对一关联关系映射
Hibernae - 双向多对一关联关系映射
51 0
|
Java 数据库连接
hibernate一对多关系操作
hibernate一对多关系操作
166 1
hibernate一对多关系操作
|
存储 Java 数据库连接
Hibernate的一对多映射的单向关联和双向关联(九)
Hibernate的一对多映射的单向关联和双向关联(九)
132 0
Hibernate的一对多映射的单向关联和双向关联(九)
|
Java 关系型数据库 数据库连接
|
SQL Java 数据库连接
JDBC上关于数据库中多表操作一对多关系和多对多关系的实现方法
黑马程序员我们知道,在设计一个Java bean的时候,要把这些BEAN 的数据存放在数据库中的表结构,然而这些数据库中的表直接又有些特殊的关系,例如员工与部门直接有一对多的关系,学生与老师直接又多对多的关系,那么这些表的关系如何表示呢?首先在建立数据库的时候就应该建立这样的对应关系。
1175 0