EFCore学习笔记(9)——加载关联数据

本文详细介绍了在EFCore中三种加载关联数据的方法:贪婪加载、显式加载和懒汉加载。贪婪加载通过Include方法一次性加载所有关联数据,包括多级和带过滤的包含。显式加载则在需要时通过DbContext.Entry加载导航属性。懒汉加载则在访问导航属性时延迟加载,可以通过代理或手动实现。此外,还讨论了EFCore6.0新增的自动包含导航的模型配置。

一、引言

如果完全跟着微软文档来学EF Core,那等学完,项目都凉透了。
光一个创建模型都有十几二十节。
所以应根据实际需要,对重点章节进行学习,一些知识点比较细的、深入的等后续要用到再学。
对我来说,除了基本的CRUD,还有一个很重要的功能就是访问相关联的表。就是点击表上的某个字段,可以跳转查看该字段相关联的表的详细信息。
而我在Query data章节中,发现了Load related data这一节,节中内容与这个功能有很大相关性。

二、 加载关联数据

1. 概述

EF Core允许你在model中使用导航属性来加载关联的实体。下面是三种常用的O/RM模式,用于加载关联数据。

  • 贪婪加载,Eager Loading,也叫预先加载,表示相关数据作为初始查询的一部分从数据库加载。
  • 显式加载,Explicit Loading,表示稍后从数据库显式加载相关数据。
  • 懒汉加载,Lazy Loading,也叫延迟加载,当访问导航属性时,相关数据才从数据库中显示加载。

2. 贪婪加载相关数据

2.1. 贪婪加载

你可以使用Include方法来指定相关数据包含在查询结果中。下面示例,结果中返回的blogs将会使其Posts属性用关联的posts填充。

Include方法的作用可以理解为让查询结果中包含xx数据

using (var context = new BloggingContext())
{
   
   
	var blogs = context.Blogs
		.Include(blog => blog.Posts)
		.ToList();
}

提示:
EF Core会自动地根据导航属性转到任何其他实体,这些实体会预先加载到上下文实例中。
因此,即使你没有显式地包含导航属性的数据,如果之前加载了一些或所有相关实体,该属性仍然可能被填充。

你可以在单个查询中包含多个关系的关联数据。

using (var context = new BloggingContext())
{
   
   
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Include(blog => blog.Owner)
        .ToList();
}

警告:
在单个查询中贪婪加载一个集合导航属性可能会带来性能问题。

2.2. 包含多级

你可以使用ThenInclude方法向下挖掘关系,来包含多级的关联数据。

using (var context = new BloggingContext())
{
   
   
	// 相当于找到更远的关联数据
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ToList();
}

还可以链接多级调用到ThenInclude上,来继续包含更多级的关联数据:

using (var context = new BloggingContext())
{
   
   
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
        .ToList();
}

你还可以合并所有调用,以在同一个查询中包含来自多个层级和多个根的相关数据。

using (var context = new BloggingContext())
{
   
   
	// 合并多个多级查询
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
        .Include(blog => blog.Owner)
        .ThenInclude(owner => owner.Photo)
        .ToList();
}

你也许希望为包含的一个实体包含多个相关实体。
例如,在查询Blogs时,你需要包含Posts,并希望同时包含Posts的Author和Tags。
要使这两者都包含在内,你需要指定从根开始的包含路径。例如,Blog -> Posts -> AuthorBlog -> Posts -> Tags。这并不意味着你会得到多余的连接;大多数情况下,EF会在生成SQL时合并这些连接。

using (var context = new BloggingContext())
{
   
   
    var blogs = context.Blogs
        .</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值