2015-02-22 3 views
0

Я работаю над приложением базы данных, которое показывает отчет о транзакции по его тегам.GroupBy в LINQ?

Это моя база данных.

Title  Amount  TagsReport (string[] array) 
Food  5   "Hotel","Friends" 
Food  6   "Hotel" 
Family  8   "Hotel","Mobile" 
Family  9   "Electricity" 
Food  8   "Party" 

Я хочу, чтобы сгенерировать отчет, как показано ниже:

Желаемая Выход:

Percentage  Title    Amount 
53%   Food    19 
        Hotel    11 
        Friends   5 
        Party    8 

57%   Family   17 
       Hotel    8 
       Mobile   8 
       Electricity  9 

не имеют достаточно знаний о LINQ. Поэтому я сталкиваюсь с множеством проблем в этом поиске идеального решения.

Однако я нахожу этот код, чтобы использовать,

var ReportingData = ReportListQuery 
    .Where(Item => Item.Category == "expense") 
    .GroupBy(item => item.Title) 
    .Select(itemGroup => new 
    { 
     Percentage = Math.Round((itemGroup.Sum(item => item.Amount)/MonthExpense) * 100), 
     ExpenseTitle = itemGroup.Key, 
     ExpenseCalculation = itemGroup.Sum(item => item.Amount), 
     TotalTagAmounts = itemGroup 
     .SelectMany(item => item.TagsReport.Select(tag => new { 
      Tag = tag, 
      Amount = item.Amount 
     }) 
     .GroupBy(tagAmount => tagAmount.Tag) 
     .Select(tagAmountGroup => new 
     { 
      Tag = tagAmountGroup.Key, 
      TotalAmount = tagAmountGroup.Sum(tagAmount => tagAmount.Amount) 
     })) 
    }); 

И выход подобен;

Percentage  Title     Amount 
53%   Food     19 
       Hotel     5 
       Friends    5 
       Hotel     6 //Hotel should be grouped here and should with the value 11 :-(
       Party     8 

57%   Family     17 
       Hotel     8 
       Mobile     8    
       Electricity   9 

Но мой желаемый результат является:

Percentage  Title    Amount 
53%   Food    19 
        Hotel    11 
        Friends   5 
        Party    8 

57%   Family   17 
       Hotel    8 
       Mobile   8 
       Electricity  9 

Как вы видите, я сделал все. Но не «отель» сгруппирован в отчетах. Что я делаю не так? Пожалуйста, порекомендуйте!

+0

Непонятно, почему это из двух групп «Название», у вас может быть процентная доля, составляющая 110%.Также непонятно, почему сумма для данной группы «Название» может считать один и тот же «тег» дважды (т. Е. Элемент, который имеет как «Hotel», так и «Friends», включен в оба) –

ответ

2

Я согласен с замечанием Криса Каммингса относительно неправильного применения группировки. Поскольку вы не сглаживаете (т. Е. Вызываете SelectMany() на поле TagsReport, пока у вас не будет только одного элемента, группировка результата завершается только одной группой для каждой сплющенной последовательности.

На основании вашего заявленного желаемого результата кажется ., что вы на самом деле есть только один неуместны закрывающую скобку вы должны написать вместо этого:

var ReportingData = ReportListQuery 
    .Where(Item => Item.Category == "expense") 
    .GroupBy(item => item.Title) 
    .Select(itemGroup => new 
    { 
     Percentage = Math.Round((itemGroup.Sum(item => item.Amount)/MonthExpense) * 100), 
     ExpenseTitle = itemGroup.Key, 
     ExpenseCalculation = itemGroup.Sum(item => item.Amount), 
     TotalTagAmounts = itemGroup 
     .SelectMany(item => item.TagsReport.Select(tag => new 
     { 
      Tag = tag, 
      Amount = item.Amount 
     })) // add parenthsis here 
     .GroupBy(tagAmount => tagAmount.Tag) 
     .Select(tagAmountGroup => new 
     { 
      Tag = tagAmountGroup.Key, 
      TotalAmount = tagAmountGroup.Sum(tagAmount => tagAmount.Amount) 
     }) // remove parenthesis here 
    }); 

другими словами: вы хотите, чтобы сгруппировать все сплющенные последовательность элементов в каждой «сгруппированных по-названием» группы, а не сглаживание каждого отдельного элемента в каждой группе. Я просто удалил второй ) на следующей строке, и добавил его непосредственно перед вторым GroupBy() звонок.

Это дает именно то, что вы описываете. Это по-прежнему нечетно (сумма отдельных сумм тегов превышает общий расход для каждой титульной группы), но, по крайней мере, это то, о чем вы специально попросили. :) (Ну, не считая процентов и hellip, учитывая данные примера, нет никакого способа получить одно значение MonthExpense, для которого проценты складываются, поэтому я просто не потрудился попытаться сделать это число правильным).

+0

Это делает мой день. Я просто хочу сказать тебе одно слово, «блестящее». –

0

Мне кажется, что ваша вторая группа выполнена за элемент, а не над группой тегов. Итак, вы группируете по названию; скажем, еда. У этой группы теперь три предмета. «Отель, друзья» - «Отель» - «Партия». Теперь, для КАЖДОЙ из этих групп, вы делаете группу по тегу. Ну, у каждой группы есть только одна. Поэтому имеет смысл, что вы увидите отель, друзей, отель, вечеринку. Мне кажется, что вы не делаете группу по всему набору, вы делаете группу на каждом члене набора. Возможно, вам захочется сохранить исходную группу в переменной, а затем суммировать результаты этого набора данных. Конечно, только суммирование предметов с одинаковыми тегами.

+0

Так как я новичок в LINQ. Не могли бы вы показать мне код? –