2012-03-19 27 views
6

Her 15 dakikada bir PowerStringHistorys ve PowerCombinerHistorys tablolarına kaydedilmiş verilerim var. LINQ için yeniyim ve veriyi her saat başı gruplandıran bir sorgu oluşturmayı ve o saat için akımı ortalama olarak hesaplamayı deniyorum. İşte ben şimdiki ortalama ve Belirtilen tarih aralığında her saati her birleştirici için kwh alabilirsiniz bugüne kadarLINQ kullanarak saatte gruplandırma

 TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); 
     DateTime UTC_StartingDate = TimeZoneInfo.ConvertTimeToUtc(StartingDate, easternZone); 
     DateTime UTC_EndingDate = TimeZoneInfo.ConvertTimeToUtc(EndingDate, easternZone); 

     var FirstQ = from p in db.PowerStringHistorys 
        join t in db.PowerStrings on p.string_id equals t.id 
        join u in db.PowerCombiners on t.combiner_id equals u.id 
        join s in db.PowerCombinerHistorys on p.recordTime equals s.recordTime 
        where p.recordTime >= UTC_StartingDate 
        where p.recordTime <= UTC_EndingDate 
        select new 
        { 
         Combiner = u.id, 
         Current = p.current, 
         RecordTime = p.recordTime, 
         Voltage = s.voltage 
        }; 

Şimdi birleştirici ve saate göre grubuna ihtiyaç var şeydir. (saatte ortalama watt)/1000 = Kwh

yüzden son bulacak çok altında gibi bir şey:

ben bir şekilde sorguda bu basit formülü uygulamak gerekir. Herhangi bir yardım büyük takdir edilecektir.

Üstü

Combiner 1  03/19/2012 1:0:0  1.85 Kwh 
Combiner 1  03/19/2012 2:0:0  1.98 Kwh 
Combiner 1  03/19/2012 3:0:0  2.05 Kwh 
Combiner 1  03/19/2012 4:0:0  2.11 Kwh 
Combiner 1  03/19/2012 5:0:0  2.01 Kwh 
Combiner 1  03/19/2012 6:0:0  1.96 Kwh 
Combiner 1  03/19/2012 7:0:0  1.85 Kwh 
Combiner 2  03/19/2012 1:0:0  1.77 Kwh 
Combiner 2  03/19/2012 2:0:0  1.96 Kwh 
Combiner 2  03/19/2012 3:0:0  2.03 Kwh 
Combiner 2  03/19/2012 4:0:0  2.11 Kwh 
Combiner 2  03/19/2012 5:0:0  2.02 Kwh 
Combiner 2  03/19/2012 6:0:0  1.98 Kwh 
Combiner 2  03/19/2012 7:0:0  1.83 Kwh 
Combiner 3  03/19/2012 1:0:0  1.77 Kwh 
Combiner 3  03/19/2012 2:0:0  1.96 Kwh 
Combiner 3  03/19/2012 3:0:0  2.03 Kwh 
Combiner 3  03/19/2012 4:0:0  2.11 Kwh 
Combiner 3  03/19/2012 5:0:0  2.02 Kwh 
Combiner 3  03/19/2012 6:0:0  1.98 Kwh 
Combiner 3  03/19/2012 7:0:0  1.83 Kwh 

DÜZENLEME benim orijinal soruydu. Aldığım iki öneriyle çalıştıktan sonra, aşağıda görüntülenen kodla sona erdim. Şu anda sadece tarihleri ​​ve toplam Kwhs'ı geri döndürüyorum. Kullanıcıların, ayrıntılarla çalışabilmeleri için filtre/sıralama/grup üzerinde bir Telerik ızgarasına ilk Q sorgu sonuçlarını görüntülemesini ve atmasını sağlamak için stringGroupedKwhlist listesini bir HighChart'a atmayı planlıyorum. Kod çalışırken ve beklediğim sonucu üretirken, verimli olduğundan emin değilim. Bir foreach kullanarak döngü yapmam gerektiğinden, çok fazla veri aldığında, yavaşlayabileceğimi tahmin ediyorum. Bunu işlemenin daha verimli bir yolu var mı?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 
using AESSmart.Models; 

namespace AESSmart.Controllers 
{ 
    public class StringKwh 
    { 
     public int CombinerID; 
     public int StringID; 
     public DateTime Interval; 
     public Double KWH; 

     public StringKwh(int combiner, int stringid, DateTime interval, double kwh) 
     { 
      CombinerID = combiner; 
      StringID = stringid; 
      Interval = interval; 
      KWH = kwh; 
     } 
    } 

    public class HomeController : Controller 
    { 
     private readonly AESSmartEntities db = new AESSmartEntities(); 

     public ActionResult Index() 
     { 
      //REPRESENTS DATE RANGE FOR A FULL DAY 
      DateTime startingDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 1); 
      DateTime endingDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59); 

      TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); 
      DateTime utcStartingDate = TimeZoneInfo.ConvertTimeToUtc(startingDate, easternZone); 
      DateTime utcEndingDate = TimeZoneInfo.ConvertTimeToUtc(endingDate, easternZone); 

      var firstQ = from p in db.PowerStringHistorys 
         from s in db.PowerCombinerHistorys 
         join t in db.PowerStrings on p.string_id equals t.id 
         join u in db.PowerCombiners on t.combiner_id equals u.id 
         where p.recordTime == s.recordTime 
         where p.recordTime >= utcStartingDate 
         where p.recordTime <= utcEndingDate 
         select new 
         { 
          Combiner = u.id, 
          StringId = p.string_id, 
          Current = p.current, 
          RecordTime = p.recordTime, 
          Voltage = s.voltage 
         }; 

      var groups = firstQ.ToList().GroupBy(q => new 
               { 
                q.Combiner, 
                q.StringId, 
                Date = q.RecordTime.Date, 
                Hour = q.RecordTime.Hour 
               }); 

      List<StringKwh> stringGroupedKwhlist = new List<StringKwh>(); 

      foreach (var group in groups) 
      { 
       stringGroupedKwhlist.Add(new StringKwh(
             group.Key.Combiner, 
             group.Key.StringId, 
             new DateTime(group.Key.Date.Year, group.Key.Date.Month, group.Key.Date.Day, group.Key.Hour, 0, 0), 
             group.Average(g => g.Voltage * g.Current)/1000d 
             )); 
      } 

      var groupCombiner = stringGroupedKwhlist.GroupBy(q => new { q.CombinerID }); 
      double myTotalKwh = 0; 

      foreach (var combinerGroup in groupCombiner) 
      { 
       myTotalKwh = Math.Round(combinerGroup.Sum(g => g.KWH), 3); 
      } 

      ViewBag.LifeTimeGeneration = myTotalKwh; 
      ViewBag.myUTCStartDate = utcStartingDate; 
      ViewBag.myUTCEndDate = utcEndingDate; 

      return View(); 
     } 

     public ActionResult About() 
     { 
      return View(); 
     } 
    } 
} 

cevap

11

Bu başlangıç ​​olabilir:

// Group by combiner ID, date, and hour 
var groups = FirstQ.ToList() 
    .GroupBy(q => new 
     { q.Combiner, Date = q.RecordTime.Date, Hour = q.RecordTime.Hour }); 

foreach (var group in groups) 
{ 
    var combinerId = group.Key.Combiner; 
    var interval = new DateTime(group.Key.Date.Year, group.Key.Date.Month, group.Key.Date.Day, group.Key.Hour, 0, 0); 

    // power = voltage * current 
    var kwh = group.Average(g => g.Voltage * g.Current)/1000d; 
} 
+0

Yanıt için teşekkürler. Aslında dize düzeyinde de gruplandırmam gerektiğini söylemeyi unutmuşum. Ben de ekledim. Çözümün işe yarıyordum, ancak bir endişem var. Lütfen yukarıdaki düzenlememi inceleyin. – Linger

2

deneyin yerine izleyen bir groupby olarak ile select:

TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); 
    DateTime UTC_StartingDate = TimeZoneInfo.ConvertTimeToUtc(StartingDate, easternZone); 
    DateTime UTC_EndingDate = TimeZoneInfo.ConvertTimeToUtc(EndingDate, easternZone); 

    var FirstQ = from p in db.PowerStringHistorys 
       join t in db.PowerStrings on p.string_id equals t.id 
       join u in db.PowerCombiners on t.combiner_id equals u.id 
       join s in db.PowerCombinerHistorys on p.recordTime equals s.recordTime 
       where p.recordTime >= UTC_StartingDate 
       where p.recordTime <= UTC_EndingDate 
       group new 
       { 
        Combiner = u.id, 
        Current = p.current, 
        RecordTime = p.recordTime, 
        Voltage = s.voltage 
       } 
       by new 
       { 
        Combiner = u.id, 
        Date = p.RecordTime.Date, 
        Hour = p.RecordTime.Hour 
       }; 
+0

aynı saatte farklı günlerde bu, okumalar yaparsanız birlikte gruplandırılacak - tarihi de gruplamaya ayırmanız gerekir. Ayrıca, emin değilim. Tüm veri sağlayıcıları için çalışacak mı - bu SQL Server'a geldiğinde bu hıçkırık olabilir. –

+0

Yanıt için teşekkürler. Çözümün işe yaramadı. Q ile ne yapacağını bilmiyor. Sorgu içinde yapılan tüm işleri alabilmek istiyorum. Bunu idare etmenin en etkili yolu olacağını düşünüyorum. – Linger

+0

@ToddGrover - Bunu çok hızlı bir şekilde yazdım - grubu koddan aldım ve lambda değişkenini değiştirmeden 'FirstQ'nun sonuna ekledim. Mevcut aralık değişkenlerini eşleştirmek için bunu güncelleyeceğim. Maalesef, kodun geri kalanını kaydırmada kaçırdığımı düşünüyorum, bu yüzden istediğin son projeksiyonların utancını durduracak; bununla birlikte, bu, büyük olasılıkla, sorgu süreklilikleriyle (yani "anahtar kelime") ve bazı daha sorgu-anlama sözdizimi ile gerçekleştirilebilir. En azından, sözdizimi hataları içermeyen bir şekilde güncellemeyi yapacağım. – devgeezer