EF Core 8:通过TestReportId获取关联的Tests列表
通过TestReportId获取关联学生的Tests列表(EF Core 8.0)
针对你的需求,这里提供几种直接可用的实现方式:
1. 基于关联字段的直接查询
如果不想依赖导航属性的预加载,可以通过多表关联直接筛选:
using (var context = new YourDbContext()) { int targetTestReportId = 123; // 替换为实际的TestReportId var studentTests = context.Tests .Join(context.ClassSchedules, test => test.ClassScheduleId, schedule => schedule.Id, (test, schedule) => new { Test = test, schedule.StudentId }) .Join(context.TestReports, combined => combined.StudentId, report => report.StudentId, (combined, report) => new { combined.Test, report.Id }) .Where(j => j.Id == targetTestReportId) .Select(j => j.Test) .ToList(); }
2. 利用导航属性的链式查询
如果模型已正确配置导航关系,用Include/ThenInclude加载关联数据后提取Tests:
using (var context = new YourDbContext()) { int targetTestReportId = 123; var testReport = context.TestReports .Include(tr => tr.Student) .ThenInclude(student => student.ClassSchedules) .ThenInclude(schedule => schedule.Tests) .FirstOrDefault(tr => tr.Id == targetTestReportId); // 提取该学生的所有Tests,空值处理避免空引用 var studentTests = testReport?.Student?.ClassSchedules .SelectMany(schedule => schedule.Tests) .ToList() ?? new List<Test>(); }
3. 轻量查询(仅加载所需数据)
如果不需要加载中间实体,直接通过SelectMany导航到Tests,性能更优:
using (var context = new YourDbContext()) { int targetTestReportId = 123; var studentTests = context.TestReports .Where(tr => tr.Id == targetTestReportId) .SelectMany(tr => tr.Student.ClassSchedules.SelectMany(schedule => schedule.Tests)) .ToList(); }
关键注意点
- 确保
DbContext的OnModelCreating方法中正确配置了一对多关系,比如:protected override void OnModelCreating(ModelBuilder modelBuilder) { // TestReport与Student的一对多(一个Student对应多个TestReport) modelBuilder.Entity<TestReport>() .HasOne(tr => tr.Student) .WithMany(s => s.TestReports) .HasForeignKey(tr => tr.StudentId); // Student与ClassSchedule的一对多 modelBuilder.Entity<Student>() .HasMany(s => s.ClassSchedules) .WithOne(cs => cs.Student) .HasForeignKey(cs => cs.StudentId); // ClassSchedule与Tests的一对多 modelBuilder.Entity<ClassSchedule>() .HasMany(cs => cs.Tests) .WithOne(t => t.ClassSchedule) .HasForeignKey(t => t.ClassScheduleId); } - 异步场景下,将
ToList()替换为ToListAsync(),FirstOrDefault()替换为FirstOrDefaultAsync(),并配合async/await使用。
内容的提问来源于stack exchange,提问作者Fayyaz Ahmed
相关产品推荐
相关产品推荐

