Include()方法适用于对象上的list。但如果我需要深入两层呢?例如,下面的方法将返回包含如下所示属性的ApplicationServers。然而,ApplicationsWithOverrideGroup是另一个包含其他复杂对象的容器。我可以在这个属性上做一个Include()吗?或者如何让该属性完全加载?
按照目前的情况,这种方法:
public IEnumerable<ApplicationServer> GetAll()
{
return this.Database.ApplicationServers
.Include(x => x.ApplicationsWithOverrideGroup)
.Include(x => x.ApplicationWithGroupToForceInstallList)
.Include(x => x.CustomVariableGroups)
.ToList();
}
将只填充Enabled属性(下面),而不填充Application或CustomVariableGroup属性(下面)。我该怎么做呢?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
public bool Enabled { get; set; }
public Application Application { get; set; }
public CustomVariableGroup CustomVariableGroup { get; set; }
}
MSDN上的EFCore示例表明,您可以使用Include和ThenInclude做一些相当复杂的事情。
这是一个很好的例子,你可以得到多么复杂的(这都是一个链式语句!):
viewModel.Instructors = await _context.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.CourseAssignments)
.ThenInclude(i => i.Course)
.ThenInclude(i => i.Enrollments)
.ThenInclude(i => i.Student)
.Include(i => i.CourseAssignments)
.ThenInclude(i => i.Course)
.ThenInclude(i => i.Department)
.AsNoTracking()
.OrderBy(i => i.LastName)
.ToListAsync();
你可以有多个Include调用-甚至在ThenInclude之后,它有点“重置”你回到顶级实体(指导者)的级别。
你甚至可以多次重复相同的“一级”集合(CourseAssignments),然后使用不同的ThenIncludes命令来获取不同的子实体。
注意,您的实际查询必须标记在Include或ThenIncludes链的末尾。以下不工作:
var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);
var first10Instructors = query.Take(10).ToArray();
强烈建议你设置日志记录,并确保你的查询不失控,如果你包括一个或两个以上的东西。了解它的实际工作原理非常重要——你会注意到每个单独的“include”通常都是一个新查询,以避免大量连接返回冗余数据。
AsNoTracking可以大大加快事情,如果你不打算实际编辑实体和保存。
EFCore 5对多组实体的查询发送到服务器的方式进行了一些更改。对于分割查询有一些新的选项,可以通过更少的连接使这种类型的某些查询更加高效,但请确保了解其限制-并启用日志记录以避免以后出现性能意外。