LINQ In Clause с Group By и TOP N записей в каждой группе - PullRequest
3 голосов
/ 06 декабря 2011

У меня есть 2 класса, как показано ниже. Если бы у меня был общий список класса Schedule, например List, как бы я написал запрос LINQ так, чтобы я мог получить все элементы в этом списке, где SourceId соответствует 1,2,3 ... X и StartTime> некоторое время, а затем я хочу вернуть первые 3 элемента для каждого SourceId (то есть: сгруппировать по SourceId)

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

Также я хочу, чтобы окончательная форма результата была в виде списка

public class Source
{
    public int SourceId { get; set; }
    public string Name { get; set; }
}

public class Schedule
{
    public int SourceId { get; set; }
    public Source Source { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

Ответы [ 2 ]

4 голосов
/ 06 декабря 2011

после нескольких часов поиска в Google:

var result = r.ScheduleList.
             Where(s => sourceIdIntArray.Contains(s.SourceId) &&
                   s.StartTime >= new DateTime(2011, 09, 20)).
             GroupBy(s => s.SourceId).
             SelectMany(g => g.OrderBy(s => s.StartTime).
                             Take(3)).
             ToList();
0 голосов
/ 06 декабря 2011

Предполагая, что:

  • нет 2 источников с одинаковым идентификатором источника
  • Вы хотите, чтобы три верхних элемента были заказаны StartTime
  • у вас все в порядке с List<KeyValuePair<int,Schedule>> в качестве результата (топ-3 сгруппированы по Source Id и все еще возвращены в виде списка)

    IEnumerable<Schedule> schedules;
    DateTime someDateTime; // date time used for comparison
    IEnumerable<int> sourceIds; // required matching source Ids
    
    schedules.OrderBy(x=>x.StartTime)
    .Where(x => x.StartTime > someDateTime)
    .GroupBy(x=>x.Source.SourceId)
    .Where(x=>sourceIds.Contains(x.Key))
    .ToDictionary(x=>x.Key, x=>x.Take(3))
    .ToList()
    
...