2013-03-23 5 views
4

Я пытаюсь создать запрос linq, который создаст коллекцию диапазонов дат с суммой значения Capacity, взятого в учетную запись, которая может перекрываться, и мне нужна сумма и определенный диапазон дат для этих перекрывающихся периодов. Благодарю.Запрос LINQ для суммирования значений в диапазонах дат

public ActionResult Index() 
     { 
      List<Capacities> _list = new List<Capacities>{ 
       new Capacities {StartDate = DateTime.Parse("01/01/2013"), StopDate = DateTime.Parse("01/01/2013 06:00"), Capacity = 100}, 
       new Capacities {StartDate = DateTime.Parse("01/01/2013 04:00"), StopDate = DateTime.Parse("01/02/2013 00:00"), Capacity = 120}, 
       new Capacities {StartDate = DateTime.Parse("01/04/2013"), StopDate = DateTime.Parse("01/04/2013 15:00"), Capacity = 100}, 
       new Capacities {StartDate = DateTime.Parse("01/04/2013 15:00"), StopDate = DateTime.Parse("01/04/2013 18:00"), Capacity = 150} 
      }; 
      //results expected 
      //01/01/2013 00:00 - 01/01/2013 04:00 100 
      //01/01/2013 04:00 - 01/01/2013 06:00 220 
      //01/01/2013 06:00 - 01/02/2013 00:00 120 
      //01/04/2013 00:00 - 01/04/2013 15:00 100 
      //01/04/2013 15:00 - 01/04/2013 18:00 150 
      return View(); 
     } 

     public class Capacities 
     { 
      public DateTime StartDate { get; set; } 
      public DateTime StopDate { get; set; } 
      public int Capacity {get;set;} 
     } 
+0

Что вы пробовали? У вас есть решение с циклами и вы хотите преобразовать его в LINQ? Вы примете решение без LINQ? –

+0

В надежде заменить старый код, который будет перемещаться по множеству и разделять перекрывающиеся диапазоны, а затем пересекать его, чтобы суммировать емкости, создающие новый массив. Да, я искал запрос linq. Благодарю. – user177194

+0

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

ответ

3

Я сделал несколько программ, но я немного расширил ваш код. Но я был в состоянии использовать LINQ в самом конце :-)

мой код:

SortedSet<DateTime> splitdates = new SortedSet<DateTime>(); 
foreach (var item in _list) 
{ 
    splitdates.Add(item.Period.Start); 
    splitdates.Add(item.Period.End); 
} 

var list = splitdates.ToList(); 
var ranges = new List<DateRange>(); 
for (int i = 0; i < list.Count - 1; i++) 
    ranges.Add(new DateRange() { Start = list[i], End = list[i + 1] }); 

var result = from range in ranges 
      from c in _list 
      where c.Period.Intersect(range) != null 
      group c by range into r 
      select new Capacities(r.Key.Start, r.Key.End, r.Sum(a => a.Capacity)); 

Полный код здесь: http://pastebin.com/wazbb1r3 Обратите внимание, что на выходе отличается из-за языка. Кроме того, некоторые бит не нужны, например DateRange.Contains().

На двух циклах выше, я понятия не имею, как преобразовать их в LINQ читаемым образом.

+0

+1 для интересного подхода (хотя я сам не пробовал код;). Но мне интересно, может ли быть общее решение таких проблем, потому что такой сценарий, как представляется, является общим для таблиц времени/расписаний. Например. Интервал от Noda Time не имеет методов проверки пересечений, которые могут быть полезны. – jCoder

+0

Фантастический! Это идеально. Этот класс DateRange очень удобен, и я очень ценю предложение linq. – user177194

Смежные вопросы