使用 linq 连接 3 个表和 select 1 列

Join 3 tables and select 1 column using linq

我有三个表 StudentTimeSheetTimeRecord

Table 列:

Student:

StudentId, FirstName, LastName

TimeSheet:

TimeSheetId, StudentId, IsActive

TimeRecord:

TimeRecordId, TimeSheetId, AddId

Table 关系:

Student样本数据:

StudentId  FirstName  LastName
------------------------------
  10       Macro      John
  11       Hiro       Edge
  12       Sarah      Lemon

TimeSheet样本数据:

TimeSheetId  StudentId  IsActive
--------------------------------
    187         10      True
    196         11      True
    195         12      True
    199         10      False
    200         12      False

TimeRecord样本数据:

TimeRecordId  TimeSheetId  Addid
--------------------------------
      1           187        1
      2           196        2
      3           187        3
      4           187        4
      5           196        5
      6           196        6
      7           195        7
      8           199        8   

如何编写 Linq 查询以获取 id = 10 学生的 addid 计数?

所以我不知道你的 class 长什么样。 我做了一个假设,您的 Student class 中没有 TimeSheets 列表(TimeSheet class 和 TimeRecords 列表也是如此)。 我的假设是基于你的问题标题,你问的是加入。

好的,一种方式:

var results1 = students
            .Join(timeSheets, student => student.StudentId, sheet => sheet.StudentId,
                (student, sheet) => new {StudentId = student.StudentId, SheetId = sheet.TimeSheetId})
            .Join(timeRecords, ss => ss.SheetId, record => record.TimeSheetId,
                (studentTimeSheet, record) => new {StudentId = studentTimeSheet.StudentId, Record = record})
            .Count(elem => elem.StudentId == 10);

还有另一种方式,通过分组 - 这样您可以获得有关所有记录的更多信息(如 AddId 列表):

var results2 = students
            .Join(timeSheets, student => student.StudentId, sheet => sheet.StudentId,
                (student, sheet) => new {StudentId = student.StudentId, SheetId = sheet.TimeSheetId})
            .Join(timeRecords, ss => ss.SheetId, record => record.TimeSheetId,
                (studentTimeSheet, record) => new {StudentId = studentTimeSheet.StudentId, Record = record})
            .GroupBy(elem => new {StudentId = elem.StudentId })
            .Select(g => new StudentTimeCount(){StudentId = g.Key.StudentId, Count = g.Count(), AddIds = g.Select(elem => elem.Record.AddId)})
            .First(student => student.StudentId == 10);

Class StudentTimeCount 看起来像这样:

public class StudentTimeCount
{
    public long StudentId { get; set; }
    public long Count { get; set; }
    public IEnumerable<long> AddIds { get; set; }
}

我不是 SQL 性能方面的专家,所以我不确定 "good" 这个查询是怎样的,如果你考虑到这一点的话。

编辑: 如果你的 classes 中有引用,你可以使用像这样简单的东西:

var result3 = students.First(student => student.StudentId == 10).TimeSheets.Sum(sheet => sheet.TimeRecords.Count);

但我不确定您需要此查询的目的是什么 - 您是否正在使用 EntityFramework 并将数据库表映射到 C# classes?或者在 LinqPad 中玩?或者什么?

我已经使用 linq 查询自行解决了它很容易解决。