C# LINQ到实体,连接两个表,然后对两个表中的列进行分组和求和

C# LINQ到实体,连接两个表,然后对两个表中的列进行分组和求和,c#,linq,entity-framework,linq-to-entities,C#,Linq,Entity Framework,Linq To Entities,正如标题所说,我的目标是在多个列上连接两个表(target和transaction),然后对该连接的结果进行分组,并对两个表中的列的值求和。以下查询仅允许访问联接中第一个表中的列 var actualsVsTargets = (from target in ObjectContext.PipelineTargets join transaction in ObjectContext.Transactions on new

正如标题所说,我的目标是在多个列上连接两个表(target和transaction),然后对该连接的结果进行分组,并对两个表中的列的值求和。以下查询仅允许访问联接中第一个表中的列

 var actualsVsTargets = (from target in ObjectContext.PipelineTargets
                 join transaction in ObjectContext.Transactions on
                    new
                    {
                        target.Year,
                        target.Quarter,
                        target.StateID,
                        target.ProductGroup.TeamId
                    } equals new
                    {
                        transaction.Year,
                        transaction.Quarter,
                        transaction.StateID,
                        transaction.Product.ProductGroup.TeamId
                    }   
                 where target.Year == year && target.ProductGroup.TeamId == teamId
                 group target by new
                                     {
                                         target.ProductGroupID,
                                         target.StateID,
                                         target.Year
                                     }
                 into targetGroup
                 select new
                            {
                                // this works fine (accessing target column)
                                TargetL1 = targetGroup.Sum(target => target.Level1_Target,
                                // this doesn't work (accessing transaction column)
                                ActualL1 = targetGroup.Sum(trans => trans.Level1_Total)
                            }).SingleOrDefault();
如下所示,这在T-SQL中实现起来很简单(大致上):


如何在LINQ中做到这一点?

首先,您应该为相关外键设置导航属性(例如,目标与事务以及从事务到产品的1:N关系)。如果设置正确,数据库设计/EF模式将承担大部分工作。然后你可以去:

(from target in targets
  where target.Year == year && target.ProductGroup.TeamId == teamId
  group target by new 
                      { 
                        target.ProductGroupID, 
                        target.StateID, 
                        target.Year 
                      } into targetGroup
  select new { Key = targetGroup.Key,
               TargetL1 = targetGroup.Sum(target => target.Level1_Target),
               ActualL1 = targetGroup.SelectMany(tg => tg.Transactions)
                                     .Sum(trans => trans.Level1_Total)
             });

但是,我无法测试它,因此可能存在错误。

事务变量超出范围。如果将其包含在分组结果中,则可以使用它

将group by子句更改为:

group new
        {
            target,
            transaction
        }
        by new
        {
            target.ProductGroupID,
            target.StateID,
            target.Year
        } into grouped
然后您的select子句可以执行以下操作:

select new
        {
            TargetL1 = grouped.Sum(groupedThing => groupedThing.target.Level1_Target,
            ActualL1 = grouped.Sum(trans => groupedThing.transaction.Level1_Total)
        }).SingleOrDefault();

谢谢,无法理解“组新{target,transaction}”部分。现在完全有道理了。
select new
        {
            TargetL1 = grouped.Sum(groupedThing => groupedThing.target.Level1_Target,
            ActualL1 = grouped.Sum(trans => groupedThing.transaction.Level1_Total)
        }).SingleOrDefault();