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

.Net Core嵌套查询获取非被评审人员工列表方法错误修正

错误原因

原查询的核心问题是类型与逻辑不匹配:x.Id是单个Guid类型值,而_context.Reviwees.Select(x => x.EmployeeId)返回的是IQueryable<Guid>类型的ID集合,直接用!=比较单个值和集合没有合法的筛选逻辑,EF Core无法将其翻译为正确的SQL语句,因此无法返回预期结果。

正确嵌套查询实现

要查询不属于被评审人的员工列表,推荐使用!Any实现嵌套查询,EF Core会将其翻译为数据库端执行的NOT EXISTS嵌套SQL,查询性能最优,代码如下:

public async Task<List<EmployeeDto>> GetEmployeeListAsync()
{
    var employeeList = await _context.Employees
        .Where(emp => !_context.Reviwees.Any(reviwee => reviwee.EmployeeId == emp.Id))
        .Select(emp => new EmployeeDto
        {
            Id = emp.Id,
            FirstName = emp.FirstName
        })
        .ToListAsync();

    return employeeList;
}

上述写法的执行逻辑:

  • 外层查询遍历所有员工记录
  • 内层嵌套查询针对当前遍历到的员工,检查Reviwees表中是否存在EmployeeId对应当前员工ID的被评审人记录
  • 取反后筛选出所有没有对应被评审人记录的员工,完全匹配需求
  • 整个查询会在数据库端完成,不会把全量表数据加载到内存,执行效率高

可选NOT IN嵌套写法

如果习惯用集合包含判断的写法,也可以使用Contains实现NOT IN逻辑的嵌套查询,代码如下:

public async Task<List<EmployeeDto>> GetEmployeeListAsync()
{
    var reviweeEmployeeIds = _context.Reviwees.Select(r => r.EmployeeId);
    var employeeList = await _context.Employees
        .Where(emp => !reviweeEmployeeIds.Contains(emp.Id))
        .Select(emp => new EmployeeDto
        {
            Id = emp.Id,
            FirstName = emp.FirstName
        })
        .ToListAsync();

    return employeeList;
}

注意:不要对reviweeEmployeeIds提前调用ToList()、ToArray()等执行方法,否则会把所有被评审人ID先加载到应用内存中再做筛选,数据量较大时会出现明显的性能问题,保持上述写法即可让EF Core生成数据库端执行的嵌套子查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:03:49