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,有所了解的同学都知道,很多时 ...
随机推荐
- 记录工作中遇到的BUG,经典的数据库时区问题和字段类型tinyint(1)问题
记录工作中发现的相对而言经典的问题 [数据库时区问题] 我个人数据库配置为CST 如下 我们测试环境的数据库配置为UTC 如下 倘若我修改了测试环境数据库时区为CST.由此造成的问题是 系统读取到数据 ...
- 详述@Responsebody和HTTP异步请求的关系
Map.ModelAndView.User.List等对象都可以作为返回值.上述这两种对象都可以使用此注解.使用此注解即表示是在同一次请求的响应体里返回.浏览器以异步http的方式来接收.比如后端的M ...
- FreeSql.Generator命令行代码生成器是如何实现的
目录 FreeSql介绍 FreeSql.Generator RazorEngine.NetCore 源码解析 FreeSql.Tools FreeSql FreeSql 是功能强大的对象关系映射技术 ...
- JAVA 字节流 与 字符流 的区别
字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 字节流 在操作时本身不会用到缓冲区(内存),是文件本身直接操作的 字符流 在操作时使用了缓冲区,通过缓冲区再操作文 ...
- C# 人脸识别库
.NET 人脸识别库 ViewFaceCore 这是基于 SeetaFace6 人脸识别开发的 .NET 平台下的人脸识别库这是一个使用超简单的人脸识别库这是一个基于 .NET Standard 2. ...
- Java 数组最佳指南,快收藏让它吃灰
两年前,我甚至写过一篇文章,吐槽数组在 Java 中挺鸡肋的,因为有 List 谁用数组啊,现在想想那时候的自己好幼稚,好可笑.因为我只看到了表面现象,实际上呢,List 的内部仍然是通过数组实现的, ...
- 1.记我的第一次python爬虫爬取网页视频
It is my first time to public some notes on this platform, and I just want to improve myself by reco ...
- P4817 Fruit Feast G
最开始拿到这道题的时候,题目中其实只规定了两种水果的饱食度,可以理解成价值或是重量,在不超过T的情况求最大值.第一眼看过去感觉就是装箱问题(背包),只不过这道题用的是完全背包,但是考虑到喝水的情况,做 ...
- centos6.4 卸载 vim7.2 安装vim7.4
一.# rpm -qa|grep vim vim-minimal-7.2.-1.8.el6.x86_64 vim-enhanced-7.2.-1.8.el6.x86_64 vim-common-7.2 ...
- Python3笔记003 - 1.3 python开发工具
第1章 认识python 1.3 python开发工具 IDLE(python自带的python shell) Pycharm(python开发的,选择专业版) 1.进入IDLE模式: C:\Prog ...