鱼和熊掌不能兼得

——中国谚语

一、介绍

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查询。

最后附上本文的demo,下载地址:http://pan.baidu.com/s/1i3IAiNF

EF性能之关联加载的更多相关文章

  1. [转]JavaScript 的性能优化:加载和执行

    原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化: ...

  2. 【转】js JavaScript 的性能优化:加载和执行

    JavaScript 的性能优化:加载和执行 转自:https://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/ 随着 Web2.0 技术的 ...

  3. EF 延迟加载和预先加载

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精   本节探讨延迟加载和预先加载 Entity Frame ...

  4. [翻译][MVC 5 + EF 6] 7:加载相关数据

    原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...

  5. EF中的贪婪加载和延迟加载(懒加载)

    在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的开销是很到的,尤其是在循环中,如果数据量不是很多的情况下还可以接受,如果数 ...

  6. EF延迟加载和懒加载

    EF默认是延迟加载的 延迟加载就是刚开始只会读取当前实体对应表的数据 关联表的数据不会读取 只有下面条件用到了才会再去读取 所以可能会造成N次读取数据库  需要在实体的属性加virtual关键字 延迟 ...

  7. 学习EF之贪懒加载和延迟加载(2)

    通过昨天对EF贪婪加载和延迟加载的学习,不难发现,延迟加载还是很好用的,但是问题也就来了,有的时候我们只需要加载一个实体,不需要和他相关的外部实体,这时候我们来看看EF延迟加载时怎么作用的吧 打开pr ...

  8. JavaScript 的性能优化:加载和执行

    随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 ...

  9. EF中的预先加载和延迟加载

    延迟加载(Lazy Loading):当实体第一次被读取时,相关数据不会被获取,只会读取本身.延迟加载的数据不会一次性查出来,而是一条一条的查询,这样就会多次请求数据库进行查询. 预先加载<Ea ...

随机推荐

  1. 。net 添加或获取文件关联

    文件关联设置 2011-02-07 14:25:36|  分类: VB.net2008或2010 |  标签:文件关联  |举报|字号 订阅     原理:以后缀名为.txt为例 方式一: 1.在注册 ...

  2. 生成树的个数——基尔霍夫定理(Matrix-Tree Theorem)

    树有很多种形态,给定结点个数,求生成不同形态二叉树的个数,显然要用到Catalan数列. 那如果给定一个图(Graph)\(G=(V,E)\),要求其最小生成树G',最好的方法莫过于Prim或Krus ...

  3. 关于GP的理解

    连续式中,CMMI有5个GG:阶段式只有3个.多出来的2个GG,一个对应的是阶段4的量化,一个是阶段5的持续优化,确保了阶段式和连续式在范围上的一致性. GG就是讲各个过程中的共有元素抽取出来,形成的 ...

  4. log4net Tutorial

    Introduction One of the greatest logging tools out there for .NET is log4net. This software is the g ...

  5. 热烈庆祝杨学明老师为苏宁、中兴、烽火、CNNIC、创维、金立、中航信等知名企业提供培训和咨询服务!

    在2015年三季度,研发资深顾问.资深讲师杨学明先生为国内多家名企提供了培训和咨询服务!由于杨学明老师在软件及互联网方面的管理经验极为丰富,被多家公司选为首席研发讲师!并聘为常年顾问!

  6. 利用dbms_metadata.get_ddl查看DDL语句

    http://www.cnblogs.com/aocle/archive/2011/10/13/2209790.html 当我们想要查看某个表或者是表空间的DDL的时候,可以利用dbms_metada ...

  7. Keepalived+tomcat的HA配置

    需要节点 NODE1—————-IP:192.168.0.2 NODE2—————-IP:192.168.0.3 VIP—————-IP:192.168.0.10 以下操作在2台机器上都要运行 先编辑 ...

  8. Q114第一颗二叉查找树(链式)

    输入n,然后n个树,建立二叉查找树.从小到大输出每个节点的左右子树,空输出# #include<cstdio> #include<iostream> using namespa ...

  9. 【Win10 UWP】QQ SDK(一):SDK基本使用方法

    每当开发一个应用需要社交分享的应用时,总是心里咯噔一下:到底什么时候分享能加上QQ和微信?除了WP8.0版本的微信SDK,官方似乎从未正面发布过适应时代发展的QQ SDK,就连后台,也没有一个可以创建 ...

  10. 第十七章:android解析JSON

    一.解析JSON数据: 首先引入包import org.json.JSONObject;(android sdk 14以后应该自带了 ) Android端的程序解析JSON和JSON数组: packa ...