EF性能之关联加载

 

鱼和熊掌不能兼得

——中国谚语

一、介绍

Entity Framework作为一个优秀的ORM框架,它使得操作数据库就像操作内存中的数据一样,但是这种抽象是有性能代价的,故鱼和熊掌不能兼得。但是,通过对EF的学习,可以避免不必要的性能损失。本篇只介绍关联实体的加载的相关知识,这在我之前的文章中都有介绍。

我们已经了解到EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy LoadingExplicit Loading都是延迟加载。

(一)Lazy Loading使用的是动态代理,默认情况下,如果POCO类满足以下两个条件,EF就使用Lazy Loading:

  1. POCO类是Public且不为Sealed。
  2. 导航属性标记为Virtual。

关闭Lazy Loading,可以将LazyLoadingEnabled设为false,如果导航属性没有标记为virtual,Lazy Loading也是不起作用的。

(二)Eager Loading使用Include方法关联预先加载的实体。

(三)Explicit Loading使用Entry方法,对于集合使用Collection,单个实体则使用Reference。

二、实例

下面通过实例来理解这几种加载方式。

有下面三个实体:Province,City,Governor,一个Province有多个City,并且只有一个Governor。

   1:      public class Province
   2:      {
   3:          public int Id { get; set; }
   4:          public string Name { get; set; }
   5:   
   6:          public virtual Governor Governor { get; set; }
   7:   
   8:          public virtual List<City> Cities { get; set; }
   9:      }
  10:   
  11:      public class City
  12:      {
  13:          public int Id { get; set; }
  14:          public string Name { get; set; }
  15:      }
  16:   
  17:   
  18:      public class Governor
  19:      {
  20:          public int Id { get; set; }
  21:          public string Name { get; set; }
  22:      }

Lazy Loading

   1:          private static void LazyLoading(EFLoadingContext ctx)
   2:          {
   3:              //发送一条查询到数据库,查询所有的province
   4:              var list = ctx.Provines.ToList();
   5:              foreach (var province in list)
   6:              {
   7:                  //每次遍历(用到导航属性时)都发送2条查询,一条查询当前province包含的city和另一条查询当前province的governor
   8:                  //如果ctx.Configuration.LazyLoadingEnabled为false或者前者为true,但是导航属性没有标注为virtual,下面的操作都会抛出异常
   9:                  Print(province);
  10:              }
  11:          }

Eager Loading

   1:          private static void EagerLoading(EFLoadingContext ctx)
   2:          {
   3:              //发送一条查询到数据库库,查询所有的province并关联city和governor
   4:              var list = ctx.Provines.Include(t => t.Cities).Include(t => t.Governor);
   5:              foreach (var province in list)
   6:              {
   7:                  //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常
   8:                  Print(province);
   9:              }
  10:          }

Explicti Loading

   1:          private static void ExplicitLoading(EFLoadingContext ctx)
   2:          {
   3:              //发送一条查询到数据库,查询所有的province
   4:              var list = ctx.Provines.ToList();
   5:              foreach (var province in list)
   6:              {
   7:                  var p = ctx.Entry(province);
   8:                  //发送一条查询,查询所有当前province的city
   9:                  p.Collection(t => t.Cities).Load();
  10:                  //发送一条查询,查询当前province的governor
  11:                  p.Reference(t => t.Governor).Load();
  12:                  //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常
  13:                  Print(province);
  14:              }
  15:          }

Print方法

   1:          private static void Print(Province province)
   2:          {
   3:              Console.WriteLine("省:【{0}】,市:【{1}】,省长:【{2}】", province.Name, string.Join(",", province.Cities.Select(t => t.Name)), province.Governor.Name);
   4:          }

三、总结

关于关联加载实体基本上就是这些内容吧,如果想看这部分详细的介绍,可以参考我这篇文章的后半部分。总的来说,这部分比较简单,一个LazyLoadingEnabled设置,三种加载方式。Lazy Loading会生成大量的sql,Eager Loading生成的关联查询比较负责,Explicit Loading同Lazy Loading一样生成很多的sql,但是有一些其他优点,比如:导航属性可以不用标注为virtual。如果这几种关联都不能解决实际问题,可以直接使用sql查询。

最新文章

  1. 使用geoserver发布arcgis切片
  2. (Array)169. Majority Element
  3. H5 浏览器开发文档
  4. Svn-如何清除eclipse中保存的svn用户名和密码
  5. Spring的lookup-method标签
  6. Codeforces gym 100685 F. Flood bfs
  7. springmvc使用aop心得
  8. 【C++模版之旅】静态多态的讨论
  9. 《阿里巴巴 Java开发手册》读后感
  10. java基础之集合框架--使用ArrayList类动态 存储数据
  11. Tunnel Warfare(线段树取连续区间)
  12. 异步Servlet和异步过虑器
  13. jmeter 测试websocket接口(一)
  14. HDU 2063 过山车 二分匹配
  15. HTTP/FTP压力测试工具siege
  16. HDU 5963 朋友(树+博弈)
  17. HTTP/2协议
  18. sessionStorage、localStorage技术相关以及商家sid、sbid记录相关、vue相关问题
  19. iis服务器php环境 failed to open stream: No such file or directory解决办法
  20. AudioTrack

热门文章

  1. C# POS 小票打印
  2. 学习Java你必须了解的知识
  3. google浏览器打开新的标签页显示http://www.google.com.hk/url?sa=p&amp;hl=zh-CN&amp;……
  4. Web前端开发最佳实践(12):JavaScript代码中有大量写死的配置数据?这些数据难以维护,你需要合理组织这些数据
  5. keras Variable set_value错误解决
  6. 快递鸟电子面单打印功能基于java
  7. nginx启动 [emerg] 12180#12948: invalid number of arguments in &quot;root&quot; directive in D:
  8. zoj 3983 Crusaders Quest 思维+枚举
  9. [ 转载 ] Okhttp的用法
  10. 基于ONVIF协议的摄像头开发总结