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

EF Core 3.1中如何编写对应多表关联分组SQL的Lambda查询

原代码问题

你原有代码存在2个核心错误:

  • 使用Any筛选关联数据仅做存在性过滤,不会实际关联TableB、TableC参与统计,计数逻辑和原SQL的内连接后统计行数的逻辑完全不符
  • 末尾冗余的二次GroupBy(g => g.Id)属于多余逻辑,和原SQL语义不符

正确Lambda写法

写法1:显式Join(和原SQL结构完全对应

var result = await _dbContext.TableA
    // 内连接TableB并前置过滤Status为Approved的条目
    .Join(
        _dbContext.TableB.Where(b => b.Status == "Approved"),
        a => a.Id,
        b => b.aId,
        (a, b) => new { A = a, B = b }
    )
    // 内连接TableC并前置过滤Scope为Scope1的条目
    .Join(
        _dbContext.TableC.Where(c => c.Scope == "Scope1"),
        ab => ab.B.Id,
        c => c.BId,
        (ab, c) => new { ab.A, C = c }
    )
    // 按TableA的三个字段分组,对应原SQL的group by逻辑
    .GroupBy(x => new { x.A.Id, x.A.Name, x.A.SomeNumber })
    // 投影输出结果
    .Select(g => new 
    {
        g.Key.Id,
        g.Key.Name,
        g.Key.SomeNumber,
        Count = g.Count()
    })
    .ToListAsync();

写法2:导航属性简化写法(如果实体已配置正确关联关系

TableA配置ICollection<TableB> TableBs导航属性、TableB配置ICollection<TableC> TableCs导航属性时可以用更简洁的写法:

var result = await _dbContext.TableA
    .SelectMany(a => a.TableBs
        .Where(b => b.Status == "Approved")
        .SelectMany(b => b.TableCs
            .Where(c => c.Scope == "Scope1")
            .Select(c => new { a, c })
        )
    )
    .GroupBy(x => new { x.a.Id, x.a.Name, x.a.SomeNumber })
    .Select(g => new 
    {
        g.Key.Id,
        g.Key.Name,
        g.Key.SomeNumber,
        Count = g.Count()
    })
    .ToListAsync();

补充说明

你原SQL中select c.Id, c.Name但group by a.Id, a.Name属于SQL语法错误,手误的可能性较高,上述代码默认按照group by的a表字段输出,如果你确实需要输出c表字段,调整Select投影部分的字段取值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:57:04