如何用LINQ获取员工最高StartDate的雇佣合同及关联表数据
获取每位员工最新雇佣合同及关联数据的解决方案
我来帮你搞定这个问题!你当前的代码只拿到了最大的StartDate,是因为最后Select的时候只提取了这个字段。要获取完整的合同记录以及关联的Employee和Department属性,我们需要找到每个EmployeeId组里对应最大StartDate的那一行数据,下面给你两种可行的实现方式:
方法一:分组后关联原表
先通过分组得到每个员工的最新合同日期,再将原合同表与这个分组结果做关联,匹配出对应记录:
var latestContracts = _dbContext.EmployementContracts .Include(x => x.Employee) // 加载关联的员工数据 .Include(x => x.Department) // 加载关联的部门数据 .Where(x => x.SupervisorId == 1) // 关联分组后的最大日期数据 .Join( // 先筛选并分组,拿到每个员工的最大StartDate _dbContext.EmployementContracts .Where(x => x.SupervisorId == 1) .GroupBy(c => c.EmployeeId) .Select(g => new { EmployeeId = g.Key, MaxStartDate = g.Max(x => x.StartDate) }), // 原表的匹配键:员工ID+合同开始日期 contract => new { contract.EmployeeId, contract.StartDate }, // 分组结果的匹配键:员工ID+最大日期 maxData => new { maxData.EmployeeId, maxData.MaxStartDate }, // 返回匹配到的原合同记录 (contract, maxData) => contract ) .ToList();
方法二:使用窗口函数(EF Core 3.0+支持)
这种方式更简洁高效,利用RowNumber()窗口函数给每个员工的合同按StartDate降序编号,取编号为1的记录就是最新合同:
var latestContracts = _dbContext.EmployementContracts .Include(x => x.Employee) .Include(x => x.Department) .Where(x => x.SupervisorId == 1) // 给每条记录添加行号,按员工分组、开始日期降序排列 .Select(x => new { Contract = x, RowNum = EF.Functions.RowNumber() .Over(PartitionBy(x.EmployeeId) .OrderByDescending(x.StartDate)) }) // 筛选出每个员工的第一条(最新)记录 .Where(x => x.RowNum == 1) // 提取完整的合同对象 .Select(x => x.Contract) .ToList();
额外说明
如果同一个员工存在多条StartDate完全相同的合同(比如同一天签了多份),上面两种方法会返回所有这些记录。如果需要只保留其中一条,可以在OrderByDescending里添加额外的排序条件,比如按ContractId降序:
.OrderByDescending(x => x.StartDate) .ThenByDescending(x => x.ContractId)
内容的提问来源于stack exchange,提问作者yes-code-hobby
相关产品推荐
相关产品推荐

