正如标题所说,我的目标是在几个列上加入两个表(目标和事务),然后对该连接的结果进行分组,并对来自BOTH表的列的值求和。以下查询仅允许访问join中的FIRST表中的列!
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中实现这一点很简单,(大致):
SELECT
targets.Year,
targets.StateID,
SUM(targets.Level1_Target) L1_Target, -- get the sum of targets
SUM(transactions.Level1_Total) L1_Total -- get the sum of transactions
FROM PipelineTargets targets
JOIN Transactions transactions
JOIN Products prods ON
transactions.ProductID = prods.ProductID
ON
targets.Year = transactions.Year and
targets.Quarter = transactions.Quarter and
targets.StateID = transactions.StateID and
prods.ProductGroupID = targets.ProductGroupID
WHERE targets.Year = '2010' and targets.StateID = 1
GROUP BY targets.Year, targets.StateID, targets.ProductGroupID
如何在LINQ中执行此操作?
答案 0 :(得分:10)
事务变量超出范围。如果将其包含在分组结果中,则可以使用它。
将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();
答案 1 :(得分:0)
首先,您应该为相关外键设置导航属性(例如,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)
});
但是,我无法测试它,因此可能存在错误。