博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)
阅读量:6417 次
发布时间:2019-06-23

本文共 6218 字,大约阅读时间需要 20 分钟。

一. 简介

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

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

1     ///  2     /// 学生表(一个学生只能有一个地址或没有地址) 3     ///  4     public class Student 5     { 6         public Student() 7         { 8  9         }10         public string studentId { get; set; }11 12         public string studentName { get; set; }13 14 15         public virtual StudentAddress StudentAddress { get; set; }16     }
1     ///  2     /// 学生地址表(一个地址只能对应一个学生) 3     ///  4     public class StudentAddress 5     { 6         public StudentAddress() 7         { 8  9         }10 11         [ForeignKey("stu")]12         //特别注意这个地方,stu对应下面的 Student stu;  13         //另外特别注意:studentAddressId,符合默认的Id生成规则,自动映射成主键,否则需要加【key】特性14         public string studentAddressId { get; set; }   15 16         public string addressName { get; set; }17 18         public virtual Student stu { get; set; }19     }

二. Lazy Loading

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

 2. 需要满足的条件:

   ①:poco类是public且不能为sealed

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

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

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

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

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

1. 延迟加载代码测试

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

2. 关闭延迟加载

1                 using (dbContext1 db = new dbContext1()) 2                 { 3                     try 4                     { 5                         Console.WriteLine("--------------------------- 02-关闭延迟加载 -----------------------------"); 6                         db.Database.Log = Console.WriteLine; 7  8                         //下面的语句为关闭延迟加载 9                         db.Configuration.LazyLoadingEnabled = false;10 11                         var list = db.Student.ToList();  //关闭延迟加载后,此处从表实体StudentAddress为null,后面不会再次查询了12                         foreach (var stu in list)13                         {14                             Console.WriteLine("学生编号:{0},学生姓名:{1}", stu.studentId, stu.studentName);15 16                             //StudentAddress为null,不会再次查询数据库,所以此处报错17                             var stuAddress = stu.StudentAddress;18                             Console.WriteLine("地址编号:{0},地址名称:{1}", stuAddress.studentAddressId, stu.studentName);19                         }20                     }21                     catch (Exception ex)22                     {23                         Console.WriteLine(ex.Message);24                     }25                 }

三. Eager Loading

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

 2. 使用步骤:

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

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

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

代码测试

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

四. Explicit Loading

 1. 又名:显示加载

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

 3. 前提:

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

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

 4. 使用步骤:

   ①:单个实体用:Reference

   ②:集合用:Collection

   ③:最后需要Load一下

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

代码测试

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

 

转载于:https://www.cnblogs.com/yaopengfei/p/7739685.html

你可能感兴趣的文章
技术成长之路(一)
查看>>
中国北方国际五金城硬件选型
查看>>
php.exe启动时提示缺少MVCR110.dall 64位 window系统 解决
查看>>
判断是否为数字方法
查看>>
[翻译] EF Core in Action 关于这本书
查看>>
js Uncaught TypeError: undefined is not a function
查看>>
[2019.2.13]BZOJ4318 OSU!
查看>>
版本号带两个小数点的,如何比较大小?( NSStringCompareOptions )
查看>>
QCustomplot使用分享(三) 图
查看>>
什么是java?
查看>>
WPF路径动画(动态逆向动画)
查看>>
Low Level Reader Protocol (LLRP) 简介
查看>>
[Micropython]TPYBoard v10x NRF24L01无线通讯模块使用教程
查看>>
mysql中show processlist过滤和杀死线程
查看>>
最新Sublime Text 2 激活 汉化
查看>>
基础数据类型之字典
查看>>
第七次作业
查看>>
Oracle中NVARCHAR2与VARCHAR2的区别
查看>>
php debug
查看>>
Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】
查看>>