LINQ to Entities, объедините две таблицы, затем сгруппируйте и возьмите суммы столбцов из обеих таблиц - PullRequest
4 голосов
/ 22 февраля 2011

Как видно из заголовка, моя цель - объединить две таблицы (цель и транзакция) по нескольким столбцам, затем сгруппировать результат этого объединения и суммировать значения столбцов из ОБА таблиц. Следующий запрос разрешает доступ только к столбцам из первой таблицы в соединении!

 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?

Ответы [ 2 ]

10 голосов
/ 22 февраля 2011

переменная транзакции находится вне области видимости.Если вы включите его в сгруппированный результат, вы сможете его использовать.

измените свою группу по предложению на:

group new
        {
            target,
            transaction
        }
        by new
        {
            target.ProductGroupID,
            target.StateID,
            target.Year
        } into grouped

, и тогда ваша фраза выбора может сделать это:

select new
        {
            TargetL1 = grouped.Sum(groupedThing => groupedThing.target.Level1_Target,
            ActualL1 = grouped.Sum(trans => groupedThing.transaction.Level1_Total)
        }).SingleOrDefault();
0 голосов
/ 22 февраля 2011

Прежде всего, вы должны настроить свойства навигации для соответствующих внешних ключей (например, отношение 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)
             });

Однако я не смог проверить это, поэтому могут быть ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...