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

SQL及LinQ实现:查询Finca并统计关联子表数据量

通用SQL解决方案

假设三张表关联规则为:TableA与TableB通过外键关联(例:TableA.id = TableB.a_id),TableB与TableC通过外键关联(例:TableB.id = TableC.b_id)。要查询TableA全量数据,同时统计每条记录关联的TableB数量、间接关联的TableC数量,可通过LEFT JOIN结合COUNT(DISTINCT)避免重复计数:

SELECT 
    a.*,
    COUNT(DISTINCT b.id) AS TableBCount,
    COUNT(DISTINCT c.id) AS TableCCount
FROM TableA a
LEFT JOIN TableB b ON a.id = b.a_id
LEFT JOIN TableC c ON b.id = c.b_id
GROUP BY a.id, a.col1, a.col2, -- 需列出TableA所有非聚合字段
         a.colN; -- 按主键+全部非聚合字段分组(不同数据库语法略有差异)
  • LEFT JOIN保证无关联数据时TableA记录仍保留,统计数为0
  • COUNT(DISTINCT)避免多表关联产生笛卡尔积导致的计数膨胀
  • 分组需包含TableA所有非聚合字段,符合标准SQL分组规则
针对Finca实体的LinQ实现

假设核心实体结构如下:

public class Finca
{
    public int ConcesionId { get; set; }
    public int PlanificacionId { get; set; }
    public int AcometidaId { get; set; }
    // 其他字段
}

public class Puntosuministroview
{
    public int ConcesionId { get; set; }
    public int PlanificacionId { get; set; }
    public int AcometidaId { get; set; }
    public int PsId { get; set; }
    // 其他字段
}

public class Contrato
{
    public int PsId { get; set; }
    // 其他字段
}

方式1:分组关联查询

var result = from f in dbContext.Fincas
             join psv in dbContext.Puntosuministroviews
                 on new { f.ConcesionId, f.PlanificacionId, f.AcometidaId } 
                 equals new { psv.ConcesionId, psv.PlanificacionId, psv.AcometidaId }
                 into psvGroup
             from psv in psvGroup.DefaultIfEmpty()
             join c in dbContext.Contratos
                 on psv.PsId equals c.PsId into cGroup
             from c in cGroup.DefaultIfEmpty()
             group new { psv, c } by f into grouped
             select new 
             {
                 Finca = grouped.Key,
                 PuntosuministroviewCount = grouped.Select(x => x.psv).Distinct().Count(),
                 ContratoCount = grouped.Select(x => x.c).Distinct().Count()
             };

方式2:子查询(逻辑更直观)

var result = from f in dbContext.Fincas
             select new
             {
                 Finca = f,
                 PuntosuministroviewCount = dbContext.Puntosuministroviews
                     .Count(psv => psv.ConcesionId == f.ConcesionId 
                                 && psv.PlanificacionId == f.PlanificacionId 
                                 && psv.AcometidaId == f.AcometidaId),
                 ContratoCount = dbContext.Contratos
                     .Count(c => dbContext.Puntosuministroviews
                         .Any(psv => psv.ConcesionId == f.ConcesionId 
                                    && psv.PlanificacionId == f.PlanificacionId 
                                    && psv.AcometidaId == f.AcometidaId 
                                    && psv.PsId == c.PsId))
             };
  • 方式2通过子查询直接统计关联数据,避免内存中处理笛卡尔积,数据量较大时更高效
  • EF Core会自动优化子查询为SQL关联语句,性能表现稳定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:45:31