You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linq查询中替换DateTime.Today为自定义日期获取缺勤员工列表?

解决指定日期员工缺勤查询问题

你的核心问题是错误使用DefaultIfEmpty和日期比较逻辑,同时忽略了AttendanceDate可能包含时间部分导致的匹配失败。以下是修正方案:

问题分析

  1. 原代码中eGroup.Where(a => a.AttendanceDate == DateTime.Today)能正常工作,是因为DateTime.Today返回的是日期为当天、时间为00:00:00的DateTime值,刚好匹配考勤记录的日期存储格式。
  2. 你尝试的两种写法存在语法错误:
    • date.DefaultIfEmpty():DefaultIfEmpty是LINQ对集合的扩展方法,不能直接用于单个DateTime变量
    • ((date).Year, (date).Month, (date).Day):这是C#元组语法,无法直接与DateTime类型的AttendanceDate做相等比较

修正后的代码

public async Task<IEnumerable<AbsentReportsViewModel>> GetAllAbsentEmpAsync(DateTime date)
{
    // 提取传入日期的纯日期部分(去掉时间),避免时间干扰匹配
    var targetDate = date.Date;

    var query = await (from e in _dbContext.Employees
                       join att in _dbContext.Attendances
                            on e.Id equals att.EmployeeId into empAttGroup
                       // 筛选该员工在指定日期的考勤记录,没有则返回null
                       from empAtt in empAttGroup.Where(a => a.AttendanceDate.Date == targetDate).DefaultIfEmpty()
                       // 没有匹配到考勤记录,即为缺勤
                       where empAtt == null
                       select new AbsentReportsViewModel
                              {
                                  JobId = e.JobId,
                                  EmpReportName = e.NameMM,
                                  DeptId = e.DeptId,
                                  RankId = e.CurrentRankId,
                                  DeptReportName = e.Department.DeptName,
                                  RankReportName = e.Rank.RankName,
                                  BarCode = e.Barcode,
                                  EmpReportId = e.Id,
                              }).ToListAsync();

    return query;
}

关键修改点

  • 日期匹配逻辑:用a.AttendanceDate.Date == targetDate替代直接相等,确保只比较日期部分,避免考勤记录中时间(如签到时间)导致的匹配失败
  • 左连接判断:将where eattt.AttendanceDate == null改为where empAtt == null,因为左连接无匹配时,empAtt整个对象为null,直接访问属性会引发空引用异常
  • 参数处理:提前提取date.Date作为目标日期,统一后续比较逻辑

额外优化建议

如果你的数据库中AttendanceDate存储的是带时间的DateTime,也可以使用EF Core的数据库函数来优化查询(避免客户端评估):

// 使用EF.Functions.TruncateTime来在数据库层面截断时间
from empAtt in empAttGroup.Where(a => EF.Functions.TruncateTime(a.AttendanceDate) == targetDate).DefaultIfEmpty()

内容的提问来源于stack exchange,提问作者Lune lune

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:12:42