01-05-01-2【Nhibernate (版本3.3.1.4000) 出入江湖】立即加载实现--NHibernateUtil.Initialize()和添加fetch关键字的HQL查询
相关资料:
http://www.cnblogs.com/lyj/archive/2008/10/29/1322373.html
问题的提出:
1.延迟加载,可能会引起session已经关闭的异常,例如:
当实现延迟加载,当需要Orders时,会通过session去查询,session。但此时,由于session已经关闭,
所以会抛出异常:
{"Initializing[Model.Customer#336]-failed to lazily initialize a collection of role: Model.Customer.Orders, no session or session was closed"}
解决方法是,使用强制立即加载:
方法一:为类添加一个方法专门用于加载Orders
public Orders LoadOrders(int customerId)
{
using (ISession _session = new SessionManager().GetSession())
{
return _session.Get<Customer>(customerId).Orders;
}
}
方法二:用NHibernateUtil.Initialize()进行强立即迟加载
public Customer Get(int customerId)
{
Customer customer = null;
ISession session = _sessionManager.GetSession();
ITransaction transaction = session.BeginTransaction();
try
{
customer = session.Get<Customer>(customerId);
//强制立即加载
NHibernateUtil.Initialize(customer.Orders);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
finally
{
session.Close();
} return customer;
} public Customer Load(int customerId)
{
Customer customer = null;
using (_session)
{
customer = _session.Load<Customer>(customerId);
//强制立即加载
NHibernateUtil.Initialize(customer.Orders);
return customer; }
}
问题的提出:
2.延迟加载,当关联的表很多,例如:
Customer--》Orders--》Product--》Company--》。。。
可能会引起连带加载过多其他实体对象,照成资源消耗。
解决方案:fetch的HQL查询:
【1】如果没有用关键fetch的HQL查询是对Orders进行延迟加载的,如下所示:
public IList<Customer> GetByHQL()
{
using (_session)
{
//注意;如果没有用关键fetch的HQL查询是对Orders进行延迟加载的,
return _session.CreateQuery("select DISTINCT c from Customer c join c.Orders ")
.List<Customer>(); }
} 测试代码:
[TestMethod]
public void TestGetByHQL()
{
CustomerService customerService = new CustomerService(); IList<Customer> customersList = customerService.GetByHQL(); //foreach (var customer in customersList)
//{
// Console.WriteLine("{0}的Order数量:{1}",
// customer.CustomerId, customer.Orders.Count());
//}
} 从下面输出的SQL语句,可以看出,没用加载Orders NHibernate:
select
distinct customer0_.CustomerId as CustomerId0_,
customer0_.Version as Version0_,
customer0_.Firstname as Firstname0_,
customer0_.Lastname as Lastname0_,
customer0_.Age as Age0_
from
Customer customer0_
inner join
[
Order] orders1_
on customer0_.CustomerId=orders1_.CustomerId
【2】在HQL查询中加入fetch进行强制立即加载
public IList<Customer> GetByHQLAndFetch()
{
using (_session)
{
//注意;如果没哟关键fetch,HQL是对Orders进行延迟加载的,
//就是通过fetch进行强制立即加载
return _session.CreateQuery("select DISTINCT c from Customer c join fetch c.Orders ")
.List<Customer>(); }
} 测试代码: [TestMethod]
public void TestGetByHQLAndFetch()
{
CustomerService customerService = new CustomerService(); IList<Customer> customersList = customerService.GetByHQLAndFetch(); //foreach (var customer in customersList)
//{
// Console.WriteLine("{0}的Order数量:{1}",
// customer.CustomerId, customer.Orders.Count());
//}
} 从下面输出的SQL语句,可以看出,添加了fetch的HQL对Orders进行了强制立即加载 NHibernate:
select
distinct customer0_.CustomerId as CustomerId0_0_,
orders1_.OrderId as OrderId1_1_,
customer0_.Version as Version0_0_,
customer0_.Firstname as Firstname0_0_,
customer0_.Lastname as Lastname0_0_,
customer0_.Age as Age0_0_,
orders1_.OrderDate as OrderDate1_1_,
orders1_.CustomerId as CustomerId1_1_,
orders1_.CustomerId as CustomerId0__,
orders1_.OrderId as OrderId0__
from
Customer customer0_
inner join
[
Order] orders1_
on customer0_.CustomerId=orders1_.CustomerId
fetch的缺陷,来自
http://www.cnblogs.com/lyj/archive/2008/10/29/1322373.html
使用HQL查询方法也可以立即加载。HQL语句支持的连接类型为:inner join(内连接)、left outer join(左外连接)、right outer join(右外连接)、full join(全连接,不常用)。
“抓取fetch”连接允许仅仅使用一个选择语句就将相关联的对象随着他们的父对象的初始化而被初始化,可以有效的代替了映射文件中的外联接与延迟属性声明。
几点注意:
- fetch不与setMaxResults() 或setFirstResult()共用,因为这些操作是基于结果集的,而在预先抓取集合时可能包含重复的数据,也就是说无法预先知道精确的行数。
- fetch还不能与独立的with条件一起使用。通过在一次查询中fetch多个集合,可以制造出笛卡尔积,因此请多加注意。对多对多映射来说,同时join fetch多个集合角色可能在某些情况下给出并非预期的结果,也请小心。
- 使用full join fetch 与 right join fetch是没有意义的。 如果你使用属性级别的延迟获取,在第一个查询中可以使用 fetch all properties 来强制NHibernate立即取得那些原本需要延迟加载的属性。
01-05-01-2【Nhibernate (版本3.3.1.4000) 出入江湖】立即加载实现--NHibernateUtil.Initialize()和添加fetch关键字的HQL查询的更多相关文章
- 01-08-05【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate二级缓存:第三方MemCache缓存
一.准备工作 [1]根据操作系统(位数)选择下载相应版本的MemCache, MemCache的下载和安装,参看: http://www.cnblogs.com/easy5weikai/p/37606 ...
- 01-03-02-2【Nhibernate (版本3.3.1.4000) 出入江湖】CRUP操作-Save方法的一些问题
此文由于当时不知道NHibernate的Sava方法不是更新操作,不知道Save就是Add,造成如下荒唐的求证过程,但结论是对的 ,可报废此文,特此声明. NHibernate--Save方法: Cu ...
- 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的一级缓存
缓存的范围? 1.事务范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结 ...
- 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态
以下属于不明来源资料: 引入 在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象.这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分这些对象,根 ...
- 01-05-01-1【Nhibernate (版本3.3.1.4000) 出入江湖】延迟加载及其class和集合(set、bag等)的Lazy属性配置组合对Get和Load方法的影响
这篇文章 http://ayende.com/blog/3988/nhibernate-the-difference-between-get-load-and-querying-by-id One o ...
- 01-04-03【Nhibernate (版本3.3.1.4000) 出入江湖】Criteria API关联查询
Criteria API关联查询 如果说HQL查询还有需要了解点SQL语法知识,并不是完全彻底面向对象查询, 那么Criterial API就是完全面向对象的查询方式. public IList< ...
- 01-04-02【Nhibernate (版本3.3.1.4000) 出入江湖】HQL查询
public IList<Customer> GetAllHql() { IList<Customer> result = null; ISession session = _ ...
- 01-07-01【Nhibernate (版本3.3.1.4000) 出入江湖】并发控制
Nhibernate 并发控制 [1]悲观并发控制 正在使用数据的操作,加上锁,使用完后解锁释放资源. 使用场景:数据竞争激烈,锁的成本低于回滚事务的成本 缺点:阻塞,可能死锁 [2]乐观并发控制: ...
- 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理
http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 管理NHibernate二级缓存 NHibernate二级缓存由ISessionF ...
随机推荐
- tcpServer 浅显的发一代码
接下来发出来的一段代码也是我从网上找的一个例子,具体的来源已经找不到了,跟作者说声抱歉 ,现在公司做机票,出于性能的原因,就重写一个底层的tcp请求(不是我写的) 下面测试的是个控制台应用程序 Htt ...
- IE8 textarea 滚动条定位不准解决方法
工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是j ...
- Java 字节流实现文件读写操作(InputStream-OutputStream)
Java 字节流实现文件读写操作(InputStream-OutputStream) 备注:字节流比字符流底层,但是效率底下. 字符流地址:http://pengyan5945.iteye.com/b ...
- C89 和 C99的标准比较
本文转载自: C89和C99标准比较 原文转载自: http://blog.programfan.com/article.asp?id=14051 http://blog.csdn.net/xgb ...
- matlab 直方图均衡化
原理: 直方图均衡化首先是一种灰度级变换的方法: 原来的灰度范围[r0,rk]变换到[s0,sk]变换函数为:s=T(r); 为便于实现,可以用查找表(look-up table)的方式存储,即:原始 ...
- 腾讯云 安全组配置及与MySQL 远程登录失败原因浅析
前言,知道自己腾讯云服务器安全组配置并在安全组里开放了所有端口的用户可以粗略的看看下边的内容,否则就仔细看看吧. 因为有学习及业务需要,我要在腾讯云上安装了CentOS7.2版本的服务器上安装MySQ ...
- PHP运行方式对比
文章内容来自以下站点http://www.cnblogs.com/xia520pi/p/3914964.html 关于PHP目前比较常见的五大运行模式: 1.CGI(通用网关接口 / Common G ...
- Vim自动补全神器:YouCompleteMe
第一次听说这个插件还是在偶然的情况下看到别人的博客,听说了这个插件的大名.本来打算在实训期间来完成安装的,无奈网实在不给力,也就拖到了回家的时候.在开始准备工作的时候就了解到这个插件不是很容易安装,安 ...
- python学习第七天
一. subprocess 模块 1. subprocess的介绍:用来替代几个老的模块或是函数,如:os.systam,os.popen,os.spawn*,os.popen2*,co ...
- Python实战(1)
此次实战完全按照Python教程 - 廖雪峰的官方网站进行 首先下载windows版本的Python2.7,附上下载链接http://www.python.org/ftp/python/2.7.6/p ...