EF性能之关联加载
鱼和熊掌不能兼得
——中国谚语
一、介绍
Entity Framework作为一个优秀的ORM框架,它使得操作数据库就像操作内存中的数据一样,但是这种抽象是有性能代价的,故鱼和熊掌不能兼得。但是,通过对EF的学习,可以避免不必要的性能损失。本篇只介绍关联实体的加载的相关知识,这在我之前的文章中都有介绍。
我们已经了解到EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Loading都是延迟加载。
(一)Lazy Loading使用的是动态代理,默认情况下,如果POCO类满足以下两个条件,EF就使用Lazy Loading:
- POCO类是Public且不为Sealed。
- 导航属性标记为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性能之关联加载的更多相关文章
- [转]JavaScript 的性能优化:加载和执行
原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化: ...
- 【转】js JavaScript 的性能优化:加载和执行
JavaScript 的性能优化:加载和执行 转自:https://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/ 随着 Web2.0 技术的 ...
- EF 延迟加载和预先加载
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本节探讨延迟加载和预先加载 Entity Frame ...
- [翻译][MVC 5 + EF 6] 7:加载相关数据
原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...
- EF中的贪婪加载和延迟加载(懒加载)
在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的开销是很到的,尤其是在循环中,如果数据量不是很多的情况下还可以接受,如果数 ...
- EF延迟加载和懒加载
EF默认是延迟加载的 延迟加载就是刚开始只会读取当前实体对应表的数据 关联表的数据不会读取 只有下面条件用到了才会再去读取 所以可能会造成N次读取数据库 需要在实体的属性加virtual关键字 延迟 ...
- 学习EF之贪懒加载和延迟加载(2)
通过昨天对EF贪婪加载和延迟加载的学习,不难发现,延迟加载还是很好用的,但是问题也就来了,有的时候我们只需要加载一个实体,不需要和他相关的外部实体,这时候我们来看看EF延迟加载时怎么作用的吧 打开pr ...
- JavaScript 的性能优化:加载和执行
随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 ...
- EF中的预先加载和延迟加载
延迟加载(Lazy Loading):当实体第一次被读取时,相关数据不会被获取,只会读取本身.延迟加载的数据不会一次性查出来,而是一条一条的查询,这样就会多次请求数据库进行查询. 预先加载<Ea ...
随机推荐
- 自己写ORM框架 SqlHelper_DG C#(java的写在链接里)
ORM框架想必大家都比较熟知了,即对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同 ...
- Titanium系列--安装Titanium Studio 中的Android SDK,JDK以及环境变量的配置(二)
Ubuntu安装配置JDK 1.先去 Oracle下载Linux下的JDK压缩包,我下载的是jdk-8u25-linux-x64.tar.gz文件,下好后直接解压 Step1:# 将解压好的jdk1. ...
- 居于集成了adt的Android 开发环境配置
一.先说一下环境 Windows 8.1 64 位 注:win7 Ultimate 64 配置会出现 Android SDK manger 不能启动的问题,是因为android.bat 里调用了fi ...
- css3 border-image 学习随笔
先上w3school数据: 对于分开设置如上表所示,没有疑惑.但是当缩写时: border-image:url(/i/border.png) 30 30 round; 一参:图片地址: 二参.三参:只 ...
- 搭建struts2框架
struts是一个经典的MVC模式拦截器比过滤器拦截的力度更大 搭建struts2框架1.引入lib包 9个(2.3版本的)common-fileupload;common-io;common-lan ...
- 4.2.2 网络编程之Socket
1基于TCP协议的Socket 服务器端首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept()方法接收客户端的数据.Accept()方法在没有数据进 ...
- day4----装饰器
装饰器本质是函数,装饰其他函数,就是为其他函数添加附加功能. 原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 实现装饰器 知识储备 1.函数即“变量 ...
- JQuery学习(表单对象属性)---checked
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 从0开始学Swift笔记整理(四)
这是跟在上一篇博文后续内容: --重写方法 重写实例方法 在子类中重写从父类继承来的实例方法和静态方法.先介绍实例方法的重写. 下面看一个示例: class Person { var n ...
- Oracle删除指定用户下所有对象
--.sql脚本 --唯一注意的是下面的d:\dropuserobj.sql为操作的.sql; --用于删除当前用户的所有对象 --use for drop all objects in curren ...