使用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 ...
随机推荐
- DHCP服务器的开始方式
方法一:采用DHCP服务器接口开启的方式 [Huawei]dhcp enable [Huawei]int g0/0/0[Huawei-GigabitEthernet0/0/0]ip add 192.1 ...
- nginx配置文件注释
#定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_processes 8; #全局错误日志定义类型,[ debug | in ...
- sqlserver无法连接
以下是我的检查信息及结果:1.telnet 192.168.1.100 1433 通过 telnet 116.3.15.198 1433 不通,提示“……无法打开连接,连接失败”的错误.2.通过端口 ...
- java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService
前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...
- vs2013专业版密钥
KCQWK-Q43V3-M3F2T-83VGV-Y6VTX
- ps命令介绍
ps是收集进程信息的重要工具.它提供的信息包括:拥有进程的用户.进程的起始时间.进程所对应的命令行路径.进程ID(PID).进程所属的终端(TTY).进程使用的内存.进程占用的CPU等.例如: $ p ...
- php get_magic_quotes_gpc()函数
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post.get.cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊 ...
- vsftpd移植
1.交叉编译 2.将生成的 vsftpd 复制到目标板 /usr/sbin 目录,vsftpd.conf 复制到目标板 /etc 目录,并添加 vsftpd 为可执行: 3.配置 使用 vi 打开 v ...
- Linux下设置网卡随系统启动
在GUI下安装RHEL,在配置网卡的时候,有时候会忘了勾选网卡随系统自动启动,解决方法是系统启动后,打开网卡配置文件/etc/sysconfig/network-script/ifcfg-eth*,将 ...
- 2287: 【POJ Challenge】消失之物
Description ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. "要使用剩下的 N - 1 物品装满容积为 x ...