第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)

时间:2022-06-16 15:06:56

一. 简介

  上一个章节中,也介绍了立即加载和延迟加载,但上一个章节是针对单表而言的,不含外键,立即也好,延迟也好,都是指单表中的数据。但本章节重点介绍的三种加载方式均是针对含(导航属性、外键)的情况下,查询主表,从表中的数据加载情况。

  下面准备两张表:Student和StudentAddress两张表,一对一 or 零 的关系,实体结构如下,通过CodeFirst来反向生成数据库。

     /// <summary>
/// 学生表(一个学生只能有一个地址或没有地址)
/// </summary>
public class Student
{
public Student()
{ }
public string studentId { get; set; } public string studentName { get; set; } public virtual StudentAddress StudentAddress { get; set; }
}
     /// <summary>
/// 学生地址表(一个地址只能对应一个学生)
/// </summary>
public class StudentAddress
{
public StudentAddress()
{ } [ForeignKey("stu")]
//特别注意这个地方,stu对应下面的 Student stu;
//另外特别注意:studentAddressId,符合默认的Id生成规则,自动映射成主键,否则需要加【key】特性
public string studentAddressId { get; set; } public string addressName { get; set; } public virtual Student stu { get; set; }
}

二. Lazy Loading

1. 又名:延迟加载、懒加载

2. 需要满足的条件:

  ①:poco类是public且不能为sealed

  ②:导航属性需要标记为Virtual

  满足以上两个条件,EF6默认就为延迟加载的模式。(默认:db.Configuration.LazyLoadingEnabled = true; )

3. 含义:每次调用子实体(外键所在的实体)的时候,才去查询数据库. 主表数据加载的时候,不去查询外键所在的从表。

4. 关闭延迟加载的办法: db.Configuration.LazyLoadingEnabled = false;

  特别注意:关闭延迟加载后,查询主表数据时候,主表的中从表实体为null.

1. 延迟加载代码测试

                 using (dbContext1 db = new dbContext1())
{
Console.WriteLine("--------------------------- 01-延迟加载 -----------------------------");
db.Database.Log = Console.WriteLine; //EF默认就是延迟加载,默认下面的语句就是true,所以下面语句注释没有任何影响
//db.Configuration.LazyLoadingEnabled = true; var list = db.Student.ToList(); //此处加载的数据,根据监测得出结论,没有对从表进行任何查询操作
foreach (var stu in list)
{
Console.WriteLine("学生编号:{0},学生姓名:{1}", stu.studentId, stu.studentName); //下面调用导航属性(一对一的关系) 每次调用时,都要去查询数据库(查询从表)
var stuAddress = stu.StudentAddress;
Console.WriteLine("地址编号:{0},地址名称:{1}", stuAddress.studentAddressId, stu.studentName);
}
}

2. 关闭延迟加载

                 using (dbContext1 db = new dbContext1())
{
try
{
Console.WriteLine("--------------------------- 02-关闭延迟加载 -----------------------------");
db.Database.Log = Console.WriteLine; //下面的语句为关闭延迟加载
db.Configuration.LazyLoadingEnabled = false; var list = db.Student.ToList(); //关闭延迟加载后,此处从表实体StudentAddress为null,后面不会再次查询了
foreach (var stu in list)
{
Console.WriteLine("学生编号:{0},学生姓名:{1}", stu.studentId, stu.studentName); //StudentAddress为null,不会再次查询数据库,所以此处报错
var stuAddress = stu.StudentAddress;
Console.WriteLine("地址编号:{0},地址名称:{1}", stuAddress.studentAddressId, stu.studentName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

三. Eager Loading

1. 又名:立即加载、贪婪加载、预加载

2. 使用步骤:

  ①:先关闭延迟加载:db.Configuration.LazyLoadingEnabled = false;

   ②:查询主表的同时通过Include把从表数据也查询出来:

3. 含义:由于查询主表的时候通过Include已经一次性将数据查询了出来,所以在调用从表数据的时候,均从缓存中读取,无须查询数据库

代码测试

           using (dbContext1 db = new dbContext1())
{
Console.WriteLine("--------------------------- 03-立即加载 -----------------------------");
db.Database.Log = Console.WriteLine; //1.关闭延迟加载
db.Configuration.LazyLoadingEnabled = false; //2. 获取主表数据的同时,通过Include将从表中的数据也全部加载出来
var list = db.Student.Include("StudentAddress").ToList();
foreach (var stu in list)
{
Console.WriteLine("学生编号:{0},学生姓名:{1}", stu.studentId, stu.studentName); //这里获取从表中的数据,均是从缓存中获取,无需查询数据库
var stuAddress = stu.StudentAddress;
Console.WriteLine("地址编号:{0},地址名称:{1}", stuAddress.studentAddressId, stu.studentName);
} }

四. Explicit Loading

1. 又名:显示加载

2. 背景:关闭延迟加载后,单纯查询主表的数据,后面又想再次查询从表,这个时候就需要用到显示加载了.

3. 前提:

  ①:关闭了延迟加载:db.Configuration.LazyLoadingEnabled = false;

  ②:单纯查询了主表,没有使用Include函数关联查询从表.

4. 使用步骤:

  ①:单个实体用:Reference

  ②:集合用:Collection

  ③:最后需要Load一下

5. 含义:关闭了延迟加载,单纯查询了主表数据,这个时候需要重新查询从表数据,就要用到显式加载了

代码测试

          using (dbContext1 db = new dbContext1())
{
Console.WriteLine("--------------------------- 04-显式加载 -----------------------------");
db.Database.Log = Console.WriteLine; //1.关闭延迟加载
db.Configuration.LazyLoadingEnabled = false; //2.此处加载的数据,不含从表中的数据
var list = db.Student.ToList();
foreach (var stu in list)
{
Console.WriteLine("学生编号:{0},学生姓名:{1}", stu.studentId, stu.studentName); //3.下面的这句话,可以开启重新查询一次数据库
//3.1 单个属性的情况用Refercence
db.Entry<Student>(stu).Reference(c => c.StudentAddress).Load();
//3.2 集合的情况用Collection
//db.Entry<Student>(stu).Collection(c => c.StudentAddress).Load(); //下面调用导航属性(一对一的关系) 每次调用时,都要去查询数据库
var stuAddress = stu.StudentAddress;
Console.WriteLine("地址编号:{0},地址名称:{1}", stuAddress.studentAddressId, stu.studentName);
} }

第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)的更多相关文章

  1. ASP&period;NET MVC深入浅出(被替换) 第一节&colon; 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节&colon; EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery &rpar; 第四节&colon; EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节&colon; EF高级属性&lpar;二&rpar; 之延迟加载、立即加载、显示加载&lpar;含导航属性&rpar; 第十节&colon; EF的三种追踪

    ASP.NET MVC深入浅出(被替换)   一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...

  2. EF实体框架-从数据库更新模型 一部分表的外键(导航属性)无法显示

    从数据库更新模型 要想让数据库表之间的外键关系 显示到实体模型的导航属性中去. 表的外键 对应另一张表的字段要是主键,唯一键显示不出来

  3. 第五节&colon; EF高级属性&lpar;一&rpar; 之 本地缓存、立即加载、延迟加载&lpar;不含导航属性&rpar;

    一. 本地缓存 从这个章节开始,介绍一下EF的一些高级特性,这里介绍的首先介绍的EF的本地缓存,在前面的“EF增删改”章节中介绍过该特性(SaveChanges一次性会作用于本地缓存中所有的状态的变化 ...

  4. 第十六节&colon; EF的CodeFirst模式通过Fluent API修改默认协定

    一. 简介 1. 优先级:Fluent API > data annotations > default conventions. 2. 所有的Fluent API配置都要在 OnMode ...

  5. Python3 Selenium自动化web测试 &equals;&equals;&gt&semi; 第六节 WebDriver高级应用 -- 操作web页面的滚动条

    学习目的: 掌握页面元素定位以外的其他重要知识点. 正式步骤: 测试Python3代码 # -*- coding:utf-8 -*- from selenium import webdriver fr ...

  6. 第一百五十六节,封装库--JavaScript,延迟加载

    封装库--JavaScript,延迟加载 延迟加载的好处,就是在浏览器视窗外的图片,不加载,拖动鼠标到浏览器视窗内后加载,用户不看的图片就不用加载,可以减少服务器大量流量 将图片的src地址用一张统一 ...

  7. ASP&period;NET MVC深入浅出系列&lpar;持续更新&rpar; ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结&lpar;3&rpar;&lpar;C&num;6&period;0和C&num;7&period;0新语法&rpar; 第三节:深度剖析各类数据结构&lpar;Array、List、Queue、Stack&rpar;及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节&colon; 总结Quartz&period;Net几种部署模式&lpar;IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  8. MVC3&plus;EF4&period;1学习系列&lpar;五&rpar;----- EF查找导航属性的几种方式

    文章索引和简介 通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种 ...

  9. EF Core反向导航属性解决多对一关系

    多对一是一种很常见的关系,例如:一个班级有一个学生集合属性,同时,班级有班长.语文课代表.数学课代表等单个学生属性,如果定义2个实体类,班级SchoolClass和学生Student,那么,班级Sch ...

随机推荐

  1. &lbrack;BZOJ2152&rsqb;聪聪可可(点分治)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2152 分析:裸的点分治,对于每课树,记录t[0],t[1],t[2]表示到当前根节点距 ...

  2. HADOOP NAMENODE对Image和edits的处理

    1.SNN CheckPoint的处理流程 配置中配置做CheckPoint的两个条件,一个是文件大小editlog大于多大就做,另一个是时间维度,多长时间做一次. (1)SNN首先检查是否需要进行c ...

  3. &lbrack;Firefly引擎&rsqb;&lbrack;学习笔记三&rsqb;&lbrack;已完结&rsqb;所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  4. Oracle 存储过程&lpar;2&rpar;

    http://www.cnblogs.com/chinafine/archive/2010/07/12/1776102.html http://blog.itpub.net/29485627/view ...

  5. MySql命令——show&comma;分页&comma;正则表达式

    先要安装MySql,过程见 MySql5.1在Win7下的安装与重装问题的解决 不是教程,还没有写教程的资格,只是为了自己查阅而已!   show show databases; //显示所有数据库 ...

  6. linux 下opensplice的简易安装

    http://www.prismtech.com/opensplice/opensplice-dds-community/software-downloads 下载对应我选择的是: OpenSplic ...

  7. go语言nsq源码解读五 nsqlookupd源码registration&lowbar;db&period;go

    本篇将讲解registration_db.go文件. 1234567891011121314151617181920212223242526272829303132333435363738394041 ...

  8. html之CSS样式学习笔记

    本文内容: 字体样式 文本样式 背景样式 尺寸样式 盒子模型 边框样式 边距样式 浮动布局 定位布局 [CSS3]伸缩布局 标签显示方式 列表样式 [CSS3]过渡样式 [CSS3]变换样式之2D变形 ...

  9. 剑指offer(63)数据流中的中位数

    题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们 ...

  10. CentOS6启动流程

    CentOS6启动流程 1.加载BIOS的硬件信息,获取第一个启动设备 在通电之后,CentOS6会进行加电自检(Power On Self Test),这个过程主要是由BIOS完成的.在自检完毕,会 ...