博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EF性能之关联加载
阅读量:5748 次
发布时间:2019-06-18

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

鱼和熊掌不能兼得

——中国谚语

一、介绍

 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
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

转载于:https://www.cnblogs.com/nianming/p/3494781.html

你可能感兴趣的文章
Oracle中如何删除某个用户下的所有数据呢
查看>>
MongoDB实战系列之五:mongodb的分片配置
查看>>
Unable to determine local host from URL REPOSITORY_URL=http://
查看>>
分析Java集合框架及数组的排序
查看>>
Java Tomcat SSL 服务端/客户端双向认证(二)
查看>>
java基础(1)
查看>>
ORACLE配置,修改tnsnames.ora文件实例
查看>>
用户无法在输入框中键入数字
查看>>
Workstation服务无法启动导致无法访问文件服务器
查看>>
Gradle:Basic Project
查看>>
.Net组件程序设计之远程调用(二)
查看>>
ant中文教程
查看>>
Linux常用命令(一)
查看>>
安装和使用 Elasticsearch
查看>>
WSUS数据库远端存储条件下切换域及数据库迁移
查看>>
JSON总结
查看>>
Tomcat启动找不到JAVA_HOME另类解决办法
查看>>
Win7下绑定IP和MAC地址提示“ARP项添加失败:拒绝访问
查看>>
tcp粘包分析
查看>>
红外遥控资料
查看>>