C#开发GET员工层级接口LINQ查询实体转int报错如何解决
问题原因
- 类型不匹配错误:
Employee类中Id为int类型、MngId为int?类型,但代码中直接将Employee类型的变量e赋值给Id,触发类型转换报错 - 变量引用错误:左连接操作后你将结果集别名设为
mngrN,但后续select中错误引用了已超出作用域的m变量 - 逻辑&性能问题:接口传入的
id参数未被使用,且提前将全表Employees加载到内存做关联,数据量大时性能极低
解决方案
快速修复(仅解决当前报错)
调整select部分的赋值逻辑,取实体的对应字段赋值即可:
[Route("empLevel/{id}")] public IActionResult GetEmpHierarchy(int id) { List<Employee> emp = entity.Employees.ToList(); List<Employee> mngr = entity.Employees.ToList(); var query = (from e in emp join m in mngr on e.MngId equals m.Id into tab1 from mngrN in tab1.DefaultIfEmpty() select new Employee { Id = e.Id, Name = e.Name, Grade = e.Grade, MngId = mngrN == null ? null : mngrN.Id }).ToList(); return Ok(query); }
优化版(推荐生产环境使用)
避免全表加载到内存,利用EF的查询能力在数据库层面执行关联操作,同时补充id参数的过滤逻辑(可根据实际业务调整过滤规则):
[Route("empLevel/{id}")] public IActionResult GetEmpHierarchy(int id) { var query = (from e in entity.Employees join m in entity.Employees on e.MngId equals m.Id into tab1 from mngrN in tab1.DefaultIfEmpty() // 示例过滤逻辑:查询指定id的员工及其直接下属,可按需修改 where e.Id == id || e.MngId == id select new Employee { Id = e.Id, Name = e.Name, Grade = e.Grade, MngId = mngrN != null ? mngrN.Id : null }).ToList(); return Ok(query); }
额外规范建议
推荐自定义DTO类接收查询结果,不要直接返回数据库映射实体,既可以避免暴露敏感字段,也能灵活扩展上级姓名等扩展字段:
// 自定义员工层级返回DTO public class EmpHierarchyDto { public int Id { get; set; } public string Name { get; set; } public double Grade { get; set; } public int? MngId { get; set; } // 可扩展上级姓名等字段 public string ManagerName { get; set; } } // 查询时直接返回DTO即可 var query = (from e in entity.Employees join m in entity.Employees on e.MngId equals m.Id into tab1 from mngrN in tab1.DefaultIfEmpty() where e.Id == id || e.MngId == id select new EmpHierarchyDto { Id = e.Id, Name = e.Name, Grade = e.Grade, MngId = mngrN != null ? mngrN.Id : null, ManagerName = mngrN != null ? mngrN.Name : "无上级" }).ToList();
内容的提问来源于stack exchange,提问作者Coder-Persona
相关产品推荐
相关产品推荐

