Home > OS >  LINQ join: selecting the last records in a one-to-many relationship
LINQ join: selecting the last records in a one-to-many relationship

Time:03-24

Let's suppose I have two tables:

  • Employees table: contains fields such as EmployeeId, DepartmentId...
  • Signings/Attendance table: contains fields such as SigningId, Time, EmployeeId, SignType (in or out)...

I am trying to select the last signing from every employee who belongs to a certain department in a certain DateTime (usually DateTime.Now) because I am developing an attendance-based application for my company.

So far I have the following query, which returns EmployeeId and SignType for all employees who meet the previous conditions (department and time). I know this query is supposed to have an extra join (left join to be exact probably thanks to this post I found yesterday) but do not really know how to proceed since it is my first time doing such complex linq queries.

Thanks a lot in advance.

from e in AppDbContext.Employees
join s in AppDbContext.Signings
on e.EmployeeId equals s.EmployeeId
where e.DepartmentId == DepartmentId
&& s.Time.Date == DateTime.Now.Date
select new Aux2()
{
   Id = e.EmployeeId,
   Type = s.SignType,
};

CodePudding user response:

You can do in this way:

var maxDateSignsByEmployee = from sign in AppDbContext.Signings.Where(s => s.Time.Date == DateTime.Now.Date)
                             group sign by sign.EmployeeId into res
                             select new{
                                 EmpId = res.Key,
                                 MaxDate = resg.Max(x => x.Time)
                             };

var list = from e in AppDbContext.Employees
          join s in AppDbContext.Signings.Where(s => maxDateSignsByEmployee.Where(m => m.EmpId == s.EmployeeId && m.MaxDate == s.Time).Count() > 0)
          on e.WorkerId equals s.EmployeeId
          where e.DepartmentId == DepartmentId
          select new Aux2()
           {
              Id = e.EmployeeId,
              Type = s.SignType,
           };

It should be what you need. It's a basic response, you can optimize it.

  • Related