简体   繁体   English

LINQ join:选择一对多关系中的最后一条记录

[英]LINQ join: selecting the last records in a one-to-many relationship

Let's suppose I have two tables:假设我有两个表:

  • Employees table : contains fields such as EmployeeId, DepartmentId... Employees 表:包含 EmployeeId、DepartmentId 等字段...
  • Signings/Attendance table : contains fields such as SigningId, Time, EmployeeId, SignType (in or out)... Signings/Attendance 表:包含 SigningId、Time、EmployeeId、SignType(进或出)等字段...

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.我正在尝试 select 在某个日期时间(通常是 DateTime.Now)属于某个部门的每个员工的最后一次签名,因为我正在为我的公司开发一个基于考勤的应用程序。

So far I have the following query, which returns EmployeeId and SignType for all employees who meet the previous conditions (department and time).到目前为止,我有以下查询,它返回满足先前条件(部门和时间)的所有员工的 EmployeeId 和 SignType。 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.我知道这个查询应该有一个额外的连接(准确地说是左连接可能要感谢我昨天发现的这篇文章)但我真的不知道如何继续,因为这是我第一次做这样复杂的 linq 查询。

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,
};

EDIT: subquery attempt编辑:子查询尝试

AppDbContext.Employees
.Where(e => e.DepartmentId == DepartmentId )
.Select(e => new Aux2(){
                        Id = e.EmployeeId,
                        Type = AppDbContext.Signings
                                      .Where(s => s.EmployeeId== e.EmployeeId && s.Time.Date==Date)
                                      .OrderByDescending(s => s.Time)
                                      .Take(1)
                                      .Select(s => s.SigType)
                                      .FirstOrDefault()
                    })

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.这是一个基本的反应,你可以优化它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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