2015-05-01 4 views
0

Итак, у меня есть небольшой кошмар, пытающийся построить запрос, хотя это действительно не должно быть так сложно.Linq Query to Group by and Sum в новый список

У меня есть класс visitItem

public class visitItem 
{ 
    public int visitId {get; set;} 
    public int contactId {get; set;} 
    public int locationId {get; set;} 
    public DateTime FirstSeen {get; set;} 
    public DateTime LastSeen {get; set;} 
    public double Duration {get; set;} 
} 

В основном я посетить дату истории в формате JSON, который я десериализации к списку visitItem и сформировать несколько различных диаграмм из данных.

То, что я хочу сделать, это создать новый список из основного списка, где я выбрать конкретный месяц, и полученный список теперь сгруппирован по ContactId и продолжительность суммируется:

List<visitItem> totalDurations = visits 
    .Where(x => x.FirstSeen.ToString("MM") == month)...... 

Так который выбирает соответствующий месяц данных, а затем я хочу список, чтобы быть похожим:

contactId   duration 
1     10 
2     5 
3     5 
4     20 

вместо:

contactId   duration 
1     5 
1     5 
2     5 
3     5 
4     10 
4     10 

Как я могу это достичь?

+0

Почему вы исполнительское строковые преобразования на всех? Разумеется, использование 'FirstSeen.Month' было бы проще ... Во всяком случае, вы не объяснили, почему * вы хотите получить первый вывод или какие входные данные ... в настоящее время вы только что сказали, что хотите, чтобы это было вместо X из Y, что дает нам очень мало контекста, с помощью которого можно помочь yuo ... –

+0

Ах - после переформатирования вопроса это имеет больше смысла. Пожалуйста, позаботьтесь, чтобы просмотреть вопрос, прежде чем публиковать его, чтобы убедиться, что это действительно имеет смысл. –

+0

Затем вы * говорите *, что вы сгруппировали контакт, но вы вообще не показали эту часть запроса, что опять-таки затрудняет помощь. В идеале, предоставить короткую, но полную программу, демонстрирующую проблему ... –

ответ

1

Вам необходимо отфильтровать по месяцам, затем группировать элементы по идентификатору контакта, а затем суммировать длительность для этих групп. Например, в мае:

var month = 5; 

var durationByContact = from visit in visits 
         where visit.FirstSeen.Month == month 
         group visit by visit.contactId 
         into visitsByContact 
         select new 
         { 
          ContactId = visitsByContact.Key, 
          TotalDuration = visitsByContact.Sum(i => i.Duration) 
         }; 

Или в синтаксисе метода:

var durationByContact = visits 
    .Where(v => v.FirstSeen.Month == month) 
    .GroupBy(v => v.contactId) 
    .Select(g => new 
    { 
     ContactId = g.Key, 
     TotalDuration = g.Sum(i => i.Duration) 
    }); 
+0

Нет, это * фильтрация * по месяцам и * группировка * по ID контакта. –

+0

@JonSkeet вы правы - вопрос редактирует объясняет лучше, я не уверен, что это было ясно раньше. Я обновил. –

+0

Спасибо за ответ. Это именно то, чего я хотел. Я только что отредактировал его для 'Select (g => new visitItem {ContactId = g.Key, Duration = g.Sum (i => i.Duration})', чтобы упростить его использование в цикле foreach и избежать списка анонимный тип. – JonnyKnottsvill