原文:https://blog.csdn.net/weixin_40719943/article/details/106960632
一、预加载
1、Include关键字
注意:
- IQueryable类型才会有Include,因此不能将Include方法放在FirstOrDefault后面
- Find方法也不支持Include,Find不属于linq的方法,它是DbSet的方法
常规语法:
_context.Enitties
.Where(...)
.Include(...)
.ToList()//FirstOrDefault()
案例:将Club关联的League和Player全部查询出来
var club = context.Clubs
.Include(e=>e.League)
.Include(e=>e.Players)
.ToList();
上面这个例子将club关联的League和Player全部查询出来了,但是Player也关联了一些数据,想把Player关联的数据也查询出来该如何操作?
2、ThenInclude:级联加载数据
注:Leagus,Players是club的关联属性
Resume和GamePlayers是Player的关联属性
Game是GamePlayers的关联属性
var club = context.Clubs
.Include(e=>e.League)
.Include(e=>e.Players)
.ThenInclude(e=>e.Resume)
.Include(e=>e.Players)
.ThenInclude(e=>e.GamePlayers)
.ThenInclude(e=>e.Game)
.ToList();
3、另一种方式实现,select关键字
注:context无法追踪匿名类,只能追踪它识别的类(DbContext中注册的类及关联类),但匿名类中有可以被是被的类仍然可以被追踪
下例中的匿名类除了Players属性,其他属性都无法被context追踪
var club = context.Clubs
.Where(e => e.Id > 0)
.Select(x => new //匿名类
{
x.Id,
LeagueName = x.League.Name,
x.Name,
Players=x.Players.Where(p=>p.DateOfBirth>new DateTime(1990,01,01)),
}).ToList();
二、显示加载关联数据:使用Collection和Reference
Collection针对关联属性是一个类的集合
Reference针对关联属性是一个单个的类
注:这种方式查询每次只能查询一个导航属性
特别的,仅追踪模式下支持这种查询,非追踪模式下不支持此种查询
追踪模式是什么?详见本系列教程–09
var club = context.Clubs.First();
context.Entry(club)
.Collection(e => e.Players)
.Load();
context.Entry(club)
.Reference(e => e.League)
.Load();
三、懒加载
懒加载在EFCore中是默认关闭的,使用懒加载会引发一系列问题,不建议使用,要使用的话参考官方文档
查询多对多关系表
Game表和Player表时多对多关系,Game和Player表在DbSet中注册,关系表GamePlayer没有在DbSet中显式体现,但被context所追踪,通过Set<>来访问
context.Set<GamePlayer>()
.Where(x => x.GameId > 0)
.ToList();