EF中延迟加载的那些事
延迟加载又称懒加载,通俗一点就是关联了一个对象,不用的时候不去查这个对象,当调用的时候再组织sql去查出这个对象的相关内容。
一.在使用EF时,我们会发现借助于框架生成的实体类中的的导航属性通常是标记 virtual的,这是为何呢?
二.让我们通过几个例子来发现其中的奥秘
下面的代码是通用的查询,先是打印了查询生成的sql,接着查询出一个Employee对象并带出对应的Dempartment对象。
using (DemoEntities db = new DemoEntities())
{
db.Database.Log = sql => Console.WriteLine(sql);
Employee emp = db.Employees.FirstOrDefault();
Console.WriteLine(emp.Name);
Console.WriteLine(emp.Department.Name);
}
1.导航属性上有virtual的情况下查询两条sql,一条是查出Employee另一条是查Dempartment
2.现在我们将默认的导航属性中的virtual去掉会发生什么呢,让我们带着疑惑继续往下看
三.原理探究
看到这是不是感觉很怪异喽,加上virtual就能正常执行,去掉就不行了么。这是啥原理呢
1.我们把代码修改一下
using (DemoEntities db = new DemoEntities())
{
Employee emp = db.Employees.FirstOrDefault();
Console.WriteLine(emp.GetType()); //打印emp的类型
Console.WriteLine(emp.GetType().BaseType); //打印emp类型对应的父类
Console.WriteLine(emp.Name);
Console.WriteLine(emp.Department.Name);
}
在原有的基础上我们打印了一下对应对象的类型
2.我们还是先看看默认有virtual的情况
通过执行代码我们发现,我们所声明的Employee的对象的类型竟然不是Employee而是一个名字特别长的另一个对象,而这个对象的父类才是Employee
3.我们将导航属性的virtual去掉再执行代码看看有什么变化
看到这里的差异,我们似乎发现了点什么。先说说virtual关键字吧,virtual是虚方法,通常是用于子类的重写。那么这里我们不难推测当导航属性有virtual关键字时,EF帮我们生成了一个
父类是Employee名字老长老长的那个类,在这个类的实现中,重写了一下,当Department为空时,它会去数据库里查一下这个Department对象,所以加上virtual关键字时就会对应两条sql
类似效果如下所示
class Employee_515EB7DF3C6168BFE9566BD863543E3AED9398AFF473BAB129D9B32823D6E8A3 : Employee {
private Department _department;
public override Department Department
{
get
{
if (_department==null)
{
//去数据库中查询Department的信息
}
return _department;
}
}
}
EF中延迟加载的那些事的更多相关文章
- 奇妙的动态代理:EF中返回的对象为什么序列化失败
今天有如鹏的学生遇到一个问题:把一个对象保存到Session中(进程外Session)后,Web服务器重启,当从Session读取这个对象的时候报错,提示是一个“T_Users”后面跟着一大串数字的类 ...
- EF中加载实体的方式
EF中的查询执行时机:1. foreach进行枚举2. ToArray.ToList.ToDictionary3. Linq的一些操作,如First.Any4. DbSet上的Load操作.DbEnt ...
- MVC ---- EF的延迟加载
//EF中的where 有延迟加载功能(Iqueryable中的where) Sys_Log pEdit = nb.Sys_Log.Where(p=>p.F_Account== "su ...
- EF使用延迟加载的本质原因
EF(Entity Framework)是微软的一个ORM框架 使用过EF的同学都知道它有一个延迟加载的功能 那么这个延迟加载的功能到底是什么? 为什么需要延迟加载? 使用延迟加载的优点和缺点又各是什 ...
- EF 学习系列三 数据操作数据加载及EF中执行Sql
1.实体状态 我们通过EF来对数据库进行操作并持久化到数据库,那么EF必然通过EF上下文来维护实体的状态,明确知道每一个状态所对应的操作.也就是说EF通过上下文负责跟踪实体的状态.EF实体状态存在命名 ...
- 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...
- 2.EF中 Code-First 方式的数据库迁移
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...
- EF中扩展出Between操作符 (修订版)
随手记录一下,这是针对原文错误的修改. 原文:EF中扩展出Between操作符 直接使用是错误的,修改后的扩展方法: /// <summary> /// 扩展 Between 操作符 // ...
- 如何在EF中实现left join(左联接)查询
在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时 ...
随机推荐
- spring源码分析——BeanPostProcessor接口
BeanPostProcessor是处理bean的后置接口,beanDefinitionMaps中的BeanDefinition实例化完成后,完成populateBean,属性设置,完成 初始化后,这 ...
- Optional 容器类
什么是Optional容器类 Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的 ...
- 本地yum源及更新
创建本地yumrepo源 概述 在生产环境中,由于网络环境隔离,很多内网机器,无法直接通过网络下载安装相关软件包,所以这个时候就需要在内网搭建一个yum源,然后通过下载将需要的软件包rpm下载下来,然 ...
- 记一次uboot升级过程的两个坑
背景 之前做过一次uboot的升级,当时留下了一些记录,本文摘录其中比较有意思的两个问题. 启动失败问题 问题简述 uboot代码中用到了一个库,考虑到库本身跟uboot版本没什么关系,就直接把旧的库 ...
- Swagger之外的选择
今天给大家安利一款接口文档生成器--JApiDocs. swagger想必大家都用过吧,非常方便,功能也十分强大.如果要说swaager有什么缺点,想必就是注解写起来比较麻烦.如果我说有一款不用写注解 ...
- JDK8--09:全新的时间API
在JDK8之前,时间有各种问题,最大的问题就是,我们使用的时间格式化类SimpleDateFormat不是线程安全的 为了更准确的说明SimpleDateFormat非线程安全,演示一个并发做时间格式 ...
- 洛谷 P2648 赚钱
这道题其实就是求最长路顺便再判断一下正环而已. 这种题肯定要用SPFA的啦,有又正边权(因为最长路所以正边就相当于负边),又是正环(同理,相当于负环),SPFA专治这种问题. 当一个点入队多次的时候, ...
- 告别传统机房:3D 机房数据可视化实现智能化与VR技术的新碰撞
前言 随着各行业对计算机依赖性的日益提高,计算机信息系统的发展使得作为其网络设备.主机服务器.数据存储设备.网络安全设备等核心设备存放地的计算机机房日益显现出它的重要地位,而机房的环境和动力设备如供配 ...
- 序列化和反序列化,请使用MessagePack
官网:https://msgpack.org/ 这个序列化的工具是今天看了dudu 的博客后去尝试使用的,果然差距很大. 对同样的对象进行序列化后,发现msgpack的大小仅有通常压缩工具Newton ...
- CentOS 的数字命令级别
1 user commands 2 system calls 3 library functions 4 special files 5 file formats 6 ...