EF之关联加载
来源:互联网 发布:suse linux 防火墙 编辑:程序博客网 时间:2024/05/21 14:49
一、介绍
Entity Framework作为一个优秀的ORM框架,它使得操作数据库就像操作内存中的数据一样,但是这种抽象是有性能代价的,故鱼和熊掌不能兼得。但是,通过对EF的学习,可以避免不必要的性能损失。本篇只介绍关联实体的加载的相关知识,这在我之前的文章中都有介绍。我们已经了解到EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Loading都是延迟加载。
(一)Lazy Loading使用的是动态代理,默认情况下,如果POCO类满足以下两个条件,EF就使用Lazy Loading:
关闭Lazy Loading,可以将LazyLoadingEnabled设为false,如果导航属性没有标记为virtual,Lazy Loading也是不起作用的。
- POCO类是Public且不为Sealed。
- 导航属性标记为Virtual。
(二)Eager Loading使用Include方法关联预先加载的实体。
(三)Explicit Loading使用Entry方法,对于集合使用Collection,单个实体则使用Reference。
二、实例
下面通过实例来理解这几种加载方式。有下面三个实体:Class(班级),Student(学生),HeadTeacher(班主任) ,一个Class有多个Student,并且只有一个HeadTeacher 。
Lazy Loadingpublic partial class Class{ public Class() { this.Student = new HashSet<Student>(); } public int Id { get; set; } public string Name { get; set; } public virtual HeadTeacher HeadTeacher { get; set; } public virtual ICollection<Student> Student { get; set; }}public partial class HeadTeacher{ public int Id { get; set; } public string Name { get; set; }}public partial class Student{ public int Id { get; set; } public string Name { get; set; }}
private static void LazyLoading(EFLoadingContext ctx){ //发送一条查询到数据库,查询所有的Class var list = ctx.Classes.ToList(); foreach (var _class in list) { //每次遍历(用到导航属性时)都发送2条查询,一条查询当前Class包含的Student和另一条查询当前Class的HeadTeacher //如果ctx.Configuration.LazyLoadingEnabled为false或者前者为true,但是导航属性没有标注为virtual,下面的操作都会抛出异常 Print(_class); }}
Eager Loading
private static void EagerLoading(EFLoadingContext ctx){ //发送一条查询到数据库库,查询所有的Class并关联Student和HeadTeacher var list = ctx.Classes.Include(t => t.Students).Include(t => t.HeadTeacher); foreach (var _class in list) { //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常 Print(_class); }}
Explicti Loading
private static void ExplicitLoading(EFLoadingContext ctx){ //发送一条查询到数据库,查询所有的Class var list = ctx.Classes.ToList(); foreach (var _class in list) { var p = ctx.Entry(_class); //发送一条查询,查询所有当前Class的Student p.Collection(t => t.Students).Load(); //发送一条查询,查询当前Class的HeadTeacher p.Reference(t => t.HeadTeacher).Load(); //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常 Print(_class); }}
Print方法
private static void Print(Class _class){ Console.WriteLine("班级:【{0}】,学生:【{1}】,班主任:【{2}】", _class.Name, string.Join(",", _class.Students.Select(t => t.Name)), _class.HeadTeacher.Name);}
三、总结
关于关联加载实体基本上就是这些内容吧,总的来说,这部分比较简单,一个LazyLoadingEnabled设置,三种加载方式。Lazy Loading会生成大量的sql,Eager Loading生成的关联查询比较负责,Explicit Loading同Lazy Loading一样生成很多的sql,但是有一些其他优点,比如:导航属性可以不用标注为virtual。如果这几种关联都不能解决实际问题,可以直接使用sql查询。 0 0
- EF之关联加载
- EF性能之关联加载
- EF性能之关联加载
- Windows服务之EF加载数据
- EF Code First 一对多、多对多关联,如何加载子集合?
- 解析ASP.NET Mvc开发之EF延迟加载
- EF Code First 数据表关联
- EF延迟加载
- EF 加载相关实体
- EF 数据延迟加载
- EF加载问题
- 【EF映射】EF原理及延迟加载
- 【EF】EF映射中的延迟加载
- one-to-one双向关联之加载
- mybaties之关联查询与延迟加载
- C# 实体模型EF关联数据库
- .net EF Join 关联表分页查询
- EF多表关联数据更新
- 机器学习的最佳入门学习资源
- 漫步IOS--日期类及其函数
- Qt入门之常用Qt标准对话框之QMessageBox
- 数据挖掘十大算法之Apriori算法原理及源码实现
- java web 基本概念
- EF之关联加载
- 我对互联网的认识
- nginx配置rtmp流媒体服务器
- vs.php中使用apache或IIS7进行外部调试
- Longest Consecutive Sequence 递归实现
- 关于spring下载源码的一点吐槽
- ARM Program Status Register 和 相关指令之笔记
- OC 自带方法 简绍 2 NSMutableString
- Objective - C基础: 第二天 - 6.关键字self的基本认识