2016-08-17 2 views
2

У меня есть список Part, который содержит значение DateTime, если они были зарегистрированы в моем Database.Показать среднее число раз в час с помощью LINQ

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

Я попытался основать свою логику моего общего среднего для этих двух значение

@{ 

var shiftChangeTime = new TimeSpan(16, 0, 0); 
<table> 
    <tr> 
     @*This is my general average*@ 
     <td>Number of part/hour</td> 
     @{ 
      var avg = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay.Hours) 
         .Average(x => x.Count()); 
      <td>@(Math.Round(avg, 2))</td> 
     } 
    </tr> 
    <tr> 
     @*This is my day average*@ 
     <td>Number of part/hour</td> 
     @{ 
      var avgDay = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay < shiftChangeTime, y => ((DateTime)y.ScanTime).TimeOfDay.Hours) 
         .Average(x => x.Count()); 
      <td>@(Math.Round(avgDay, 2))</td> 
     } 
    </tr> 
    <tr> 
     @*This is my night average*@ 
     <td>Number of part/hour for night shift</td> 
     @{ 
      var avgNight = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay > shiftChangeTime, y => ((DateTime)y.ScanTime).TimeOfDay.Hours) 
         .Average(x => x.Count()); 
      <td>@(Math.Round(avgNight, 2))</td> 
     } 
    </tr> 
</table> 
} 

В настоящее время я застрял с логикой отделения дневной/ночной смены на час основе.

На данный момент он разделил мое общее число на две части.

Любая идея о том, как действовать?

ответ

1

Проблема с вашим кодом выше то, что после GroupBy дневной/ночной смены вам также необходимо сгруппировать по Hour, чтобы сделать среднечасовое число.

Это дает среднее значение деталей в час в течение дня/ночные смены:

List<Part> Model = new List<Part> 
{ 
    new Part{ ScanTime = new DateTime(2016,1,1,1,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,7,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,12, 0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,17,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,19,0,0) }, 
    new Part{ ScanTime = new DateTime(2016,1,1,23,0,0) }, 
}; 

var shiftChangeTime = new TimeSpan(12, 0, 0); 

var result = Model.GroupBy(x => x.ScanTime.TimeOfDay < shiftChangeTime ? "Day" : "Night") 
    .Select(g => new 
    { 
     Shift = g.Key, 
     Average = g.GroupBy(item => item.ScanTime.Hour, 
          (key, group) => new { Hour = key, Amount = group.Count() }) 
        .Average(y => y.Amount) 
    }).ToList(); 

Другой вариант, если вы не хотите 2 GroupBy сначала использовать Where оставить только записи определенного сдвига, а затем остальное:

var dayAverage = Model.Where(x => x.ScanTime.TimeOfDay < shiftChangeTime) 
         .GroupBy(item => item.ScanTime.Hour, 
           (key, group) => new { Hour = key, Amount = group.Count() }) 
         .Average(y => y.Amount); 
+0

Если я правильно понял ваш код «результат» должен содержать 2 значения, один из которых является средним значением дневной смены, а второй - средним значением ночной смены? Я обращаюсь к ним, выполняя 'result [" day "]/result [" night "]', правильно? – Chax

+1

@Chax - вам нужно получить к нему доступ, как 'result [0]'. Если вы хотите получить доступ так, как вы написали, вместо «ToList' do' ToDictionary' –

+0

Отлично! Благодарю. Я попробую это сразу и подтвержу, если это работает. – Chax