[翻译 EF Core in Action 2.4] 加载相关数据
Entity Framework Core in Action
Entityframework Core in action是 Jon P smith 所著的关于Entityframework Core 书籍。原版地址. 是除了官方文档外另一个学习EF Core的不错途径, 书中由浅入深的讲解的EF Core的相关知识。因为没有中文版,所以本人对其进行翻译。 预计每两天一篇更新 PS: 翻译难免限于本人水平有不准确的地方,建议英文水平不错的同学直接查看原版,有不足的地方欢迎指正
第一部分目录导航
加载相关数据
之前我向你展示了Book实体类,它有其他三个实体的导航属性: PriceOffer,Review和BookAuthor. 下面介绍如何使用代码访问这些数据. 你有以下方式加载数据: 贪婪加载,显式加载,选择加载和懒加载(在EF Core 2.1中)
有一点很重要,EF Core默认不会加载实体类的任何关系(导航属性),如果加载了Book类,在默认情况下Book实体的每个导航属性都为null
默认不加载任何关系的行为是正确的,这意味着EF Core最小化了数据库访问. 如果你想加载一个关系则添加需要代码告诉EF Core. 下面介绍三种方法,以及它们的优缺点
贪婪加载: 加载与主实体类的关系
加载相关数据的第一种方法是贪婪加载. 贪婪加载需要告诉EF Core在加载主实体数据的查询中加载导航属性. 使用两个方法Include和ThenInClude指定预先加载. 下个清单展示了Book实体类实例查询Books表的第一行数据以及贪婪加载单个关系Reviews

- EF6 EF Core的贪婪加载与EF 6.x的方法类似, 但EF Core改进了语法和SQL实现. EF 6.x没有ThenInclude方法, 并且EF 6.x的sql实现是尝试在一个查询中加载所有数据和集合,这样的SQL查询很可能是低效的. EF Core在一个单独的查询中加载集合,你可以在前面的SQL部分看到这一点
下面我们看一个更复杂的例子,下面的清单展示了查询第一本书并且贪婪加载它所有的关系.

之前展示了使用贪婪加载方法Include获取AuthorsLink关系(一级关系),直接由加载的实体类引用的关系. Include后面使用ThenInclude加载二级关系,本例中是BookAuthor的Author表. 这种方式(Include后面使用ThenInclude)是访问深层次关系的标准方法,你可以使用更多的ThenInclude深入更深的关系
如果数据不存在,比如Book类的Promotion属性指向的可选PriceOffer类,Include不会失败,它只是加载不到任何东西,如果是集合会返回一个空集合. ThenInclude也是这样. 如果前面的Include或Theninclude为空,后面的ThenInclude会被忽略
贪婪加载的缺点是会加载所有的数据,有时你不需要某些部分数据,例如图书列表不需要书籍描述,而图书描述一般会很长.
注: 在EF Core2.0中,如果你在查询中使用了不必要的Include方法,则会有一个警告,比如 context.Books.Include(b => b.Promotion).Where( b => b.Promotion.NewPrice > 10).Select(b => b.BookId) 代码中使用了include,但它是不必要的,因为查询只返回了BookId. EF Core团队为此情况添加了警告,因为没有必要使用Inlcude方法.
显式加载: 在加载了实体类之后加载关系
第二个方法是显式加载,加载了主实体类之后,使用显式加载其他所需的关系. 下面的代码首先加载了书籍,然后使用显式加载命令读取所有关系

显式加载有一个额外的命令,在加载数据的同时并且可用查询. 下面的代码展示了使用显式加载方法Query命令查询评论数量并加载每个评论的所有星级评分. 你可以在Query方法后使用LINQ命令,例如Where,Orderby等

显式加载的优点是不会立即加载实体的关系. 这对于在某些情况下需要相关数据,显式加载会很有用. 你还会发现在复杂业务逻辑中显式加载也很有用
显式加载的缺点是会产生更多的数据库往返,这可能是低效的. 如果你事先知道所需的数据,那么贪婪加载通常会更好,因为加载关系所需的数据库往返次数更少
选择加载: 加载实体类的特定属性和关系
第三种方法是使用LINQ的Select方法明确的选择需要的数据,我称之为选择加载. 下面展示了使用Select方法从Book类中选择属性,在查询中执行特定的代码获取书的评论数量

Select查询方法的优点是只加载你需要的数据,在你不需要所有的数据时,这会很有用. 上面的查询代码只需要一个Select SQL命令获取所有数据. 在数据库往返次数方面也很少. EF Core将查询的p.Reviews.Count转换为SQL命令,在数据库中完成计数. 如下面的SQL所示
SELECT TOP(1) [p].[Title], [p].[Price], (
SELECT COUNT(*)
FROM [Review] AS [r0]
WHERE [p].[BookId] = [r0].[BookId] )
FROM [Books] AS [p]
选择加载的缺点是需要为每个属性/计算编写代码. 这会很繁琐, 在10.3节中我介绍了一种自动化的方法
注: 在本章的后面,你会看到更复杂的选择加载案例,我们会使用这种类型的加载构建图书应用程序的图书列表查询
EF Core 2.1中的延迟加载
在EF 6.x中将属性标记为virtual,在读取到该属性时会进行数据库访问. 延迟加载添加到了EF Core 2.1中
喜欢延迟加载的人说,延迟加载很容易使用,在读取属性时不需要应用程序数据库上下文. 延迟加载的缺点是对延迟加载的数据进行更多的数据库访问. 让查询变慢, 本章描述的三种方法在我看来完全可以消除延迟加载的存在意义,它们可以带来性能更高的数据库访问
[翻译 EF Core in Action 2.4] 加载相关数据的更多相关文章
- [翻译] EF Core in Action 关于这本书
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译][MVC 5 + EF 6] 7:加载相关数据
原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...
- [翻译 EF Core in Action 2.0] 查询数据库
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.9] 掀开EF Core的引擎盖看看EF Core内部是如何工作的
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 2.3] 理解EF Core数据库查询
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.10] 应该在项目中使用EF Core吗?
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.11] 何时不应该使用EF Core
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
随机推荐
- 用Python完成毫秒级抢单,助你秒杀淘宝大单
目录: 引言 环境 需求分析&前期准备 淘宝购物流程回顾 秒杀的实现 代码梳理 总结 0 引言 年中购物618大狂欢开始了,各大电商又开始了大力度的折扣促销,我们的小胖又给大家谋了一波福利,淘 ...
- WPF Button IsMouseOver Background
https://stackoverflow.com/questions/17259280/how-do-you-change-background-for-a-button-mouseover-in- ...
- linq,skip(),take实现分页
using (AdventureWorks2012Entities db = new AdventureWorks2012Entities()) { int num = (from stu in db ...
- JS运算符类型
一.运算符类型 1.算术运算符: 用于各类数值运算,包括加(+).减(-).乘(*).除(/).求余(或称模运算,%).自增(++).自减(--)共七种. 2.关系运算符: 用于比较运算.包括大于(& ...
- CTF必备技能丨Linux Pwn入门教程——栈溢出基础
这是一套Linux Pwn入门教程系列,作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的一些题目和文章整理出一份相对完整的Linux Pwn教程. 课程回顾>>Linux ...
- Django restframework 序列化之 ModelSerializer 小记
首先介绍一下相关概念 序列化器(Serializer) 1. 自定义型: 继承rest_framework.serializers.Serializer 2. 模型类型: 继承rest_frame ...
- 在VideoFileClip函数中获取“OSError:[WinError 6]句柄无效”
我正在使用python通过导入moviepy库创建一个程序,但收到以下错误: from moviepy.editor import VideoFileClip white_output = 'vide ...
- 关与 @EnableConfigurationProperties 注解
@EnableConfigurationProperties注解的作用是: 让使用 @ConfigurationProperties 注解的类生效. 当@EnableConfigurationProp ...
- shell 字符菜单管理
1.创建一个脚本func.sh 脚本如下func2.sh #!/bin/bash function menu(){ title="My Menu" url="www.la ...
- SQLAlchemy(1)
介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并获取 ...