简体   繁体   中英

Join 3 tables and select 1 column using linq

I have three tables Student , TimeSheet and TimeRecord .

Table columns:

Student :

StudentId, FirstName, LastName

TimeSheet :

TimeSheetId, StudentId, IsActive

TimeRecord :

TimeRecordId, TimeSheetId, AddId

Table relationships:

  • Student 1:N TimeSheet (FK StudentId)
  • TimeSheet 1:N TimeRecord (FK TimeSheetId)

Student sample data:

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

TimeSheet sample data:

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

TimeRecord sample data:

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   

How to write a Linq query to get count of the addid for the student with id = 10 ?

so I don't know, how your classes look like. I made an assumption, that you DO NOT have a list of TimeSheets in your Student class (the same for TimeSheet class and list of TimeRecords). My assumption is based on your question title, where you asking about join.

Ok, one way:

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);

And another way, with grouping - so you can get more information, about all your record (like AddId lists):

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 looks like this:

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

I am not specialist about SQL performance, so I am not sure, how "good" is this query, if you take this into an account.

EDIT: If you have references in your classes, you can use something as simple as:

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

But I am not really sure what you need this query for - are you using EntityFramework and map database tables to C# classes? Or playing in LinqPad? Or what?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM