2012-03-19 10 views
6

15分ごとにPowerStringHistorysテーブルとPowerCombinerHistorysテーブルにデータが記録されています。私はLINQの初心者です。毎時ごとにデータをグループ化し、その時間平均で現在のクエリを作成する方法を理解しようとしています。ここで私は私が電流を平均化し、指定した日付範囲のすべての時間のために、各コンバイナのためのキロワット時を得ることができるので、これまでLINQを使用した時間単位のグループ化

 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 
        }; 

は、今私は、コンバイナと時間によってグループに必要持っているものです。 (時間あたりの平均ワット)/ 1000 =キロワット時

だから私はで終了するかを以下のようなものがある:

は私が何とかクエリで、この単純な公式を適用する必要があります。どんな助けでも大歓迎です。

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 

EDIT

上記は私の元の質問でした。私が受け取った2つの提案で作業した後、私は下に表示されているコードに終わった。今は、日付と総Kwhをビューに戻しています。私は文字列GroupedKwhlistリストをHighChartにスローして、最初のクエリ結果をTelerikグリッドに表示してスローして、ユーザーがフィルタリング/ソート/グループ化して詳細を処理できるようにする計画です。コードは機能し、私が期待している結果を生み出す一方で、効率的であるとは確信していません。私はforeachを使用して循環しなければならないので、それが遅くなる可能性がある多くのデータを取得したら、私は推測しています。これを処理するより効率的な方法はありますか?

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(); 
     } 
    } 
} 

答えて

11

これあなたが始めるかもしれません:

// 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

お返事ありがとうございます。私は実際に文字列レベルでグループ化する必要があることに言及するのを忘れていました。だから私はそれを加えました。私はあなたの解決策を働かせることができましたが、私は心配しています。上記の私の編集を確認してください。 – Linger

2

次のようgroupbyselectを交換してみてください:

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

これを行う場合は、同じ時間に別の日に測定値一緒にグループ化されます - あなたは、グループにも日付を作業する必要があります。また、.Hourがすべてのデータプロバイダで動作するかどうかはわかりませんが、これはSQL Serverに到達するときに問題になる可能性があります。 –

+0

お返事ありがとうございます。私はあなたの解決策を働かせることができませんでした。それはqと何をするべきかを知らない。私はすべての作業をクエリ内で行うことができるようにしたいと思います。私はそれがそれを処理する最も効率的な方法だと思います。 – Linger

+0

@ToddGrover - 私はこれを少し早く書いた - 私はあなたのコードからgroup-byを取り出し、lambda変数を変更せずに 'FirstQ'の最後に追加しました。私はこれをレンジ変数に合わせて更新します。残念ながら、私はスクロールのコードの残りの部分を逃したと思うので、これはあなたが望む最終的な予測を恥ずかしがります。しかし、これもおそらくクエリ継続(すなわち、 'into'キーワード)といくつかのクエリ理解構文で実現できます。私は、少なくとも構文エラーのないように更新する予定です。 – devgeezer

関連する問題