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

将SQL多表关联分组统计查询转换为EF LINQ查询的疑问

将SQL多表分组统计转换为EF LINQ查询

我来帮你搞定这个转换问题!结合你给出的实体类、ViewModel以及原始SQL逻辑,我整理了两种可行的LINQ实现方案,你可以根据自己的编码习惯选择:

方案一:利用实体导航属性(推荐)

你的实体类已经定义了完整的关联导航关系(Company包含offices集合,Office包含employees集合),用导航属性写LINQ会更简洁,也更符合EF的设计思路:

// 与原始SQL的INNER JOIN逻辑完全一致:仅返回有办公点且办公点存在员工的公司
var viewModel = _context.Companies
    // 过滤掉无办公点或办公点无员工的公司
    .Where(c => c.offices.Any(o => o.employees.Any()))
    .Select(c => new MyViewModel
    {
        company = c,
        // 统计唯一员工数:展开所有办公点的员工,提取ID去重后计数
        employeeCount = c.offices.SelectMany(o => o.employees)
                                 .Select(e => e.id)
                                 .Distinct()
                                 .Count(),
        // 统计办公点数量:直接取当前公司的办公点总数(天然唯一,无需额外去重)
        officeCount = c.offices.Count()
    })
    .ToList();

如果不需要过滤(想返回所有公司,无办公点/员工的计数自动为0),直接去掉Where条件即可。

方案二:显式Join写法(贴近原始SQL)

如果你更习惯SQL的Join语法,可以用这种方式,核心是先完成多表关联,再按公司分组统计:

var viewModel = from c in _context.Companies
                join o in _context.Offices on c.id equals o.companyId
                join e in _context.Employees on o.id equals e.officeId
                // 按公司对象分组,将关联的办公点、员工打包到分组集合中
                group new { c, o, e } by c into grouped
                select new MyViewModel
                {
                    company = grouped.Key,
                    // 提取分组内所有员工ID,去重后计数
                    employeeCount = grouped.Select(g => g.e.id).Distinct().Count(),
                    // 提取分组内所有办公点ID,去重后计数
                    officeCount = grouped.Select(g => g.o.id).Distinct().Count()
                };

关键逻辑对应说明:

  • SQL中的COUNT(DISTINCT 字段)对应LINQ的Select(字段).Distinct().Count(),先提取目标字段去重,再统计数量。
  • SQL中的GROUP BY Company.name在LINQ中通过group ... by c实现(因为Company的id是唯一标识,按整个公司对象分组等价于按name分组,同时能完整保留公司实体信息)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:03:19