EF Core 通过延迟加载获取导航属性数据
EF 6及以前的版本是默认支持延迟加载(Lazy Loading
)的,早期的EF Core中并不支持,必须使用Include
方法来支持导航属性的数据加载。
当然在EF Core 2.1及之后版本中已经引入了延迟加载功能,详细实现原理可以查看官网(传送门)。
下面记录一下,分别使用Include
和Lazy Loading
来支持导航属性的数据加载。
Entity数据库实体
简单的一个多对多关系,分别对应数据库中的3张表。学生和学校之间通过StuSchReg关联,相互之间可以通过导航属性获取数据。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IList<StuSchReg> Regs { get; set; }
}
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IList<StuSchReg> Regs { get; set; }
}
public class StuSchReg
{
public int Id { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Student Student { get; set; }
public int SchId { get; set; }
[ForeignKey("SchId")]
public virtual School School { get; set; }
}
通过导航属性获取数据
数据查询需求:通过学校Id获取学校中所有学生的信息
[HttpGet]
[HttpPost]
public async Task<JsonResult> Test(int id)
{
return await Task.Run(() =>
{
var school = dbContext.School.Find(id);
var list = school.Regs.Select(d => new { d.Student.Id, d.Student.Name });
return Success(list);
});
}
这种情况下school.Regs
会报错(未将对象引用到实例),断点查看会发现值为null。
解决方法:
1.通过Include
直接加载导航属性
将获取school的语句修改一下,可以正常获取到数据。
var school = dbContext.School
.Include(d => d.Regs)
.ThenInclude(d => d.Student)
.FirstOrDefault(d => d.Id == id);
2.开启EF Core的延迟加载功能
使用延迟加载的最简单方式是安装 Microsoft.EntityFrameworkCore.Proxies 包,并通过调用 UseLazyLoadingProxies 来启用。
例如:在DbContext的OnConfiguring
方法中启用
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
}
或在使用AddDbContext
时启用
services.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
EF Core会为可重写的任何导航属性(必须是 virtual 且在可被继承的类上)启用延迟加载。
这时候还原为最开始的调用方式,也可以正常获取到导航属性的数据了。
var school = dbContext.School.Find(id);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构