使用 linq 连接 3 个表和 select 1 列
Join 3 tables and select 1 column using linq
我有三个表 Student
、TimeSheet
和 TimeRecord
。
Table 列:
Student
:
StudentId, FirstName, LastName
TimeSheet
:
TimeSheetId, StudentId, IsActive
TimeRecord
:
TimeRecordId, TimeSheetId, AddId
Table 关系:
- 学生1:N时间表(FK StudentId)
- TimeSheet 1:N TimeRecord (FK TimeSheetId)
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 查询自行解决了它很容易解决。
我有三个表 Student
、TimeSheet
和 TimeRecord
。
Table 列:
Student
:
StudentId, FirstName, LastName
TimeSheet
:
TimeSheetId, StudentId, IsActive
TimeRecord
:
TimeRecordId, TimeSheetId, AddId
Table 关系:
- 学生1:N时间表(FK StudentId)
- TimeSheet 1:N TimeRecord (FK TimeSheetId)
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 查询自行解决了它很容易解决。