使用NHibernate(8)-- 延迟加载
1,延迟加载。
延迟加载,即用到的时候再加载数据。这种机制是非常有情怀的,比如一篇中的用户实体有标签、问题等导航属性,如果只是用到用户名去查询整个实体,则把相关的标签和问题也都加载,性能会比较低。而有了延迟加载机制之后就可以做到查询用户实体只加载用户数据,访问到标签或问题等属性的时候再去加载这些数据。
如果使用Linq To NHibernate,则可以使用Linq提供的延迟加载机制,对于这种,是linq提供的机制,就不讨论了。
需要注意的是,如果查询出用户实体之后,关闭了Session。则延迟加载的时候会抛出异常。这是因为关闭session数据库连接被关闭,无法继续查询数据。
NHibernate默认是开启延迟加载的,也可以通过Lazy="false"属性关闭某个属性的延迟加载机制,这时会立即加载。
可以通过查看生成的sql来验证这种情况,再此就不写示例代码了。
2,延迟加载的原理。
延迟加载一般是通过代理模式来实现的,NHibernate会为我们的实体生成一个继承与该实体的代理,并重写父类的方法(这也是NHibernate要求我们的实体属性都必须是Virtual的原因)。
比如对于我们的User类,会生类似如下的代理类:
public class UserProxy:User
{
public override List<Question> Questions
{
get
{
base.Questions = ...//加载数据
return base.Questions;
}
set
{
base.Questions = value;
}
}
}
因为继承的关系,所以把代理类赋值给User类是没有问题的,同时由于多态,调用User的Question的时候实际调用的是代理类的属性。
3,方法Get和Load的区别。
Session有两个查询数据的方法,及Get和Load。Get方法会立即从数据库加载对象,而Load方法返回的是一个代理对象,当使用这个代理对象时,再去查询数据库,从而实现延迟加载。
这一点也可以通过监视生成的sql来实现。
4,Linq To NHibernate中的立即查询。
有时候,我们明确知道在某个业务逻辑中会用到当前实体的某个导航属性,希望查询的时候一次查询出来提高效率,而不是先加载实体,再加载导航属性。这时候可以用Linq To NHibernate中的立即查询来实现。
NHibernate提供了四种方法:Fetch及ThenFetch,FetchMany及ThenFetchMany。
Fetch用来加载关联关系,加载User的同时加载导航属性Question集合:
var users = session.Query<User>().Fetch(u=>u.Questions).ToList();
如果Question实体又包含Answer的导航属性,希望也一并加载出来,则可以使用ThenFetch:
var users = session.Query<User>().FetchMany(u=>u.Questions).ThenFetch(q=>q.Answers).ToList();
对于Fetch和FetchMany的区别:
针对上面的代码Fetch返回的是Question集合,不能针对返回结果继续ThenFetch。
而FetchMany返回的是Question,可以对其结果继续进行ThenFetch。
使用NHibernate(8)-- 延迟加载的更多相关文章
- [NHibernate]延迟加载
目录 写在前面 文档与系列文章 延迟加载 一个例子 总结 写在前面 上篇文章介绍了多对多关系的关联查询的sql,HQL,Criteria查询的三种方式.本篇文章将介绍nhibernate中的延迟加载方 ...
- NHibernate系列文章二十一:延迟加载
摘要 NHibernate的延迟加载机制是很重要的内容.通过关系映射将数据库表之间的关系映射成对象之间的关系,如果没有延迟加载机制,从主表的一个对象的查询将直接查询出所有与该对象关联的其他对象,如果关 ...
- Nhibernate cookbook 3.0-翻译
/* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-ts ...
- NHibernate教程(13)--立即加载
本节内容 引入 立即加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过上一篇的介绍,我们知道了NHibernate中默认的加载机制--延迟加载.其本质就是使用GoF23中代理模式 ...
- 在 NHibernate 中一切必须是 Virtual 的吗?
原文地址:Must Everything Be Virtual With NHibernate? 老赵在博文中 我对NHibernate的感受(2):何必到处都virtual 提到这篇文章,顺便翻译一 ...
- NHibernate Linq查询 扩展增强 (第九篇)
在上一篇的Linq to NHibernate的介绍当中,全部是namespace NHibernate命名空间中的IQueryOver<TRoot, TSubType>接口提供的.IQu ...
- (转)EntityFramework之领域驱动设计实践
EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领 ...
- EntityFramework之领域驱动设计实践
EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领 ...
- 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 ...
随机推荐
- .NET 扩展方法
.NET 的扩展方法是在.NET 3.0引入的,MSDN给出的定义是:扩展方法使你能够向现有类型“添加”方法(包括你自定义的类型和对象噢),而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩 ...
- MySQL主从同步的延迟原理
1. MySQL数据库主从同步延迟原理. 答:谈到MySQL数据库主从同步延迟原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlo ...
- HTML、CSS和JS
一.html 1.web流程中的HTML HTML---->赤裸裸的人 CSS ---->穿华丽的衣服 JS ---->让人动起来 浏览器和server端之间的通信本质上是字 ...
- QtCreator动态编译jsoncpp完美支持x86和arm平台
如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson-------------- ...
- SSO(单点登录)
自己动手写SSO(单点登录) 标签: sso 登录 | 发表时间:2014-03-02 15:01 | 作者: 分享到: 出处:http://www.iteye.com SSO在我们的应用中非常常见, ...
- Java设计模式——组合模式
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...
- oracle11g 修改字符集
查看当前字符集SQL语句: select * from nls_database_parameters where parameter ='NLS_CHARACTERSET'; 修改字符集操作如下,首 ...
- JS之延迟处理
$(document).ready(function () { $("#zidong3,#zidong1").click(function () { $("#zidong ...
- Scrum Meeting (Oct. 27 2014)
软件工程是一门十分有意思的课程,它不仅锻炼了我们开发软件的能力,更是给了我们结队作业的机会,在团队协作中,我们学会了欣赏别人,学会了品鉴自己,学会了如何集思广益凝聚成一个锐意进取的集体.继单人单词查询 ...
- Spring 4 官方文档学习(十一)Web MVC 框架之编码式Servlet容器初始化
在Servlet 3.0+ 环境中,你可以编码式配置Servlet容器,用来代替或者结合 web.xml文件.下面是注册DispatcherServlet : import org.springfra ...