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

EF 6.1中Linq连表填充OverDueEquipVM及分组报错求助

解决方案

第一步:修正视图模型定义

先修复VM的语法错误:

public class OverDueEquipVM 
{
    public int EmployeeId { get; set; }
    public int ManagerId { get; set; }
    public string EmployeeName { get; set; } // 员工全名:First + Last
    public string ManagerName { get; set; } // 经理全名
    public DateTime CheckOutDate { get; set; } // 借出日期
    public string EquipType { get; set; } // 设备类型:手机/笔记本等
}

第二步:编写正确的Linq查询

下面的查询会关联EmployeeTable获取员工和经理信息,过滤逾期超过一周的设备,按员工姓名分组,组内按逾期日期降序,最终投影到OverDueEquipVM:

// 计算一周前的日期,用于判断逾期
var oneWeekAgo = DateTime.Now.Date.AddDays(-7);

var overDueList = db.LaptopsTable
    // 关联员工表,获取员工姓名
    .Join(db.EmployeeTable,
          laptop => laptop.EmployeeId,
          emp => emp.EmpID,
          (laptop, emp) => new { laptop, emp })
    // 关联员工表(作为经理表),获取经理姓名
    .Join(db.EmployeeTable,
          joinResult => joinResult.emp.MgrID,
          mgr => mgr.EmpID,
          (joinResult, mgr) => new { joinResult.laptop, joinResult.emp, mgr })
    // 过滤逾期超过一周的设备
    .Where(x => x.laptop.CheckOutDate.Date <= oneWeekAgo)
    // 如果需要只查询登录用户相关的设备,保留下面这行;否则删除
    // .Where(x => x.laptop.EmployeeId == userId)
    // 先按逾期日期降序排序
    .OrderByDescending(x => x.laptop.CheckOutDate)
    // 按员工姓名分组
    .GroupBy(x => x.emp.FirstName + " " + x.emp.LastName)
    // 将分组数据投影到VM
    .SelectMany(group => group.Select(item => new OverDueEquipVM
    {
        EmployeeId = item.emp.EmpID,
        ManagerId = item.mgr.EmpID,
        EmployeeName = $"{item.emp.FirstName} {item.emp.LastName}",
        ManagerName = $"{item.mgr.FirstName} {item.mgr.LastName}",
        CheckOutDate = item.laptop.CheckOutDate,
        EquipType = item.laptop.EqipType // 注意字段名拼写,你VM里是EquipType,表中是EqipType,建议统一命名
    }))
    .ToList();

关键说明

  • 关联经理表:通过两次Join操作,第一次关联员工本人,第二次通过员工的MgrID关联经理的记录;
  • 逾期判断:用DateTime.Now.Date.AddDays(-7)计算一周前的日期,只要设备借出日期早于这个日期,就判定为逾期;
  • 分组与排序:先按逾期日期降序,再按员工姓名分组,最后通过SelectMany将分组后的设备展开为VM列表;
  • 字段拼写统一:注意你表中字段是EqipType,VM里是EquipType,建议修改为一致的命名,避免后续维护问题。

如果经理可能存在为空的情况(比如部分员工没有经理),可以将第二次Join改为左连接:

.Join(db.EmployeeTable.DefaultIfEmpty(),
      joinResult => joinResult.emp.MgrID,
      mgr => mgr?.EmpID,
      (joinResult, mgr) => new { joinResult.laptop, joinResult.emp, mgr })

同时在投影ManagerName时做空值处理:ManagerName = mgr != null ? $"{mgr.FirstName} {mgr.LastName}" : "无经理"


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:43