LINQ Group通过多表Inner Join和聚合函数

时间:2014-01-24 09:24:35

标签: c# linq group-by linq-to-entities aggregate-functions

我有以下Linq to EF查询:

from envelope in ENVELOPEs.AsNoTracking()
join spool in SPOOLs.AsNoTracking() on envelope.SPOOL_ID equals spool.SPOOL_ID
join extract in EXTRACTs.AsNoTracking() on spool.EXTRACT_ID equals extract.EXTRACT_ID
join extractProfile in EXTRACT_PROFILE.AsNoTracking() on extract.EXTRACT_PROFILE_ID equals extractProfile.EXTRACT_PROFILE_ID
join box in BOXes.AsNoTracking() on envelope.BOX_ID equals box.BOX_ID
join pallet in PALLETs.AsNoTracking() on box.PALLET_ID equals pallet.PALLET_ID
join fakeCap in FAKECAPs.AsNoTracking() on envelope.FAKECAP_ID equals fakeCap.FAKECAP_ID
join envWeightRange in ENVELOPE_WEIGHT_RANGE.AsNoTracking() on envelope.ENV_WEIGHT_RANGE_ID equals envWeightRange.ENV_WEIGHT_RANGE_ID
join ptype in PTYPEs.AsNoTracking() on spool.PTYPE_ID equals ptype.PTYPE_ID
join envType in ENVTYPEs.AsNoTracking() on ptype.ENVTYPE_ID equals envType.ENVTYPE_ID
join boxType in BOXTYPEs.AsNoTracking() on envType.BOXTYPE_ID equals boxType.BOXTYPE_ID
where spool.JSHEET_ID == 8
orderby envWeightRange.ENV_WEIGHT_RANGE_CODE,
    fakeCap.FAKECAP_DEST_TARIF
group new { envelope, envType } by
new 
{ 
    fakeCap.FAKECAP_DEST_TARIF,
    envWeightRange.ENV_WEIGHT_RANGE_CODE    
} into grouped
select new
{
    FAKECAP_DEST_TARIF = grouped.Key.FAKECAP_DEST_TARIF,
    ENV_WEIGHT_RANGE_CODE = grouped.Key.ENV_WEIGHT_RANGE_CODE,
    ENVTYPE_COD_OMOLOG = grouped.Max(item => item.ENVTYPE_COD_OMOLOG), // Error: ENVTYPE_COD_OMOLOG not defined
    TOTALE_BUSTE = grouped.Count()
}

未能说明未定义提交的ENVTYPE_COD_OMOLOG。 (对不起,我本来希望在那里粘贴整个异常,但是对于操作系统语言环境设置并不是非常不相同的。)

但是如果我在组中包含字段ENVTYPE_COD_OMOLOG而没有使用聚合函数访问它,那么它可以完美地运行:

from envelope in ENVELOPEs.AsNoTracking()
join spool in SPOOLs.AsNoTracking() on envelope.SPOOL_ID equals spool.SPOOL_ID
join extract in EXTRACTs.AsNoTracking() on spool.EXTRACT_ID equals extract.EXTRACT_ID
join extractProfile in EXTRACT_PROFILE.AsNoTracking() on extract.EXTRACT_PROFILE_ID equals extractProfile.EXTRACT_PROFILE_ID
join box in BOXes.AsNoTracking() on envelope.BOX_ID equals box.BOX_ID
join pallet in PALLETs.AsNoTracking() on box.PALLET_ID equals pallet.PALLET_ID
join fakeCap in FAKECAPs.AsNoTracking() on envelope.FAKECAP_ID equals fakeCap.FAKECAP_ID
join envWeightRange in ENVELOPE_WEIGHT_RANGE.AsNoTracking() on envelope.ENV_WEIGHT_RANGE_ID equals envWeightRange.ENV_WEIGHT_RANGE_ID
join ptype in PTYPEs.AsNoTracking() on spool.PTYPE_ID equals ptype.PTYPE_ID
join envType in ENVTYPEs.AsNoTracking() on ptype.ENVTYPE_ID equals envType.ENVTYPE_ID
join boxType in BOXTYPEs.AsNoTracking() on envType.BOXTYPE_ID equals boxType.BOXTYPE_ID
where spool.JSHEET_ID == 8
orderby envWeightRange.ENV_WEIGHT_RANGE_CODE,
    fakeCap.FAKECAP_DEST_TARIF
group new { envelope, envType } by
new 
{ 
    fakeCap.FAKECAP_DEST_TARIF,
    envWeightRange.ENV_WEIGHT_RANGE_CODE,
    envType.ENVTYPE_COD_OMOLOG
} into grouped
select new
{
    FAKECAP_DEST_TARIF = grouped.Key.FAKECAP_DEST_TARIF,
    ENV_WEIGHT_RANGE_CODE = grouped.Key.ENV_WEIGHT_RANGE_CODE,
    ENVTYPE_COD_OMOLOG = grouped.Key.ENVTYPE_COD_OMOLOG,
    TOTALE_BUSTE = grouped.Count()
}

1 个答案:

答案 0 :(得分:2)

在该查询中,groupedIGrouping<TKey,T>,其中:

  • T是投影类型,在本例中为new { envelope, envType }

  • TKey是分组键,在这种情况下(不包括ENVTYPE_COD_OMOLOG):

    new { 
        fakeCap.FAKECAP_DEST_TARIF,
        envWeightRange.ENV_WEIGHT_RANGE_CODE
    }
    

IGrouping<TKey,T>除了拥有属性TKey Key之外,还可以被视为IEnumerable<T>。这意味着要从每个组中获得最大ENVTYPE_COD_OMOLOG,您需要按以下方式更改您的选择(Max将适用于T的序列):

select new
{
    FAKECAP_DEST_TARIF = grouped.Key.FAKECAP_DEST_TARIF,
    ENV_WEIGHT_RANGE_CODE = grouped.Key.ENV_WEIGHT_RANGE_CODE,
    ENVTYPE_COD_OMOLOG = grouped.Max(item => item.envType.ENVTYPE_COD_OMOLOG),
    TOTALE_BUSTE = grouped.Count()
}

这样您就不需要按ENVTYPE_COD_OMOLOG进行分组,并且仍然可以在结果中获得每组的最大值。