Mam dane są rejestrowane co 15 minut w tabelach PowerStringHistorys i PowerCombinerHistorys. Jestem nowy w LINQ i próbuję wymyślić, jak utworzyć zapytanie grupujące moje dane o każdej godzinie, a dla tej godziny średnią bieżącą. Oto co mam tak dalekoGrupowanie według godziny przy użyciu 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
};
Teraz muszę grupy przez sumator i godzinę, więc mogę średnio prąd i uzyskać kWh dla każdego łączącego za każdą godzinę określonym zakresie dat.
muszę zastosować ten prosty wzór w zapytaniu jakoś: (średnie watów na godzinę)/1000 = kWh
Więc co będę kończyć coś jak poniżej. Każda pomoc będzie bardzo ceniona.
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
Przede był moim oryginalne pytanie. Po pracy z dwiema sugestiami, które otrzymałem, skończyłem z kodem wyświetlanym poniżej. W tej chwili właśnie zwracam daty i łączną liczbę Kwhs do widoku. Mam zamiar rzucić listę stringGroupedKwhlist do HighChart, aby użytkownik mógł wyświetlić i rzucić wyniki pierwszego zapytania do siatki Telerik, aby użytkownik mógł filtrować/sortować/grupować, aby mogli pracować ze szczegółami. Chociaż kod działa i daje oczekiwany wynik, nie jestem pewien, czy jest skuteczny. Ponieważ muszę przechodzić przez foreach, domyślam się, że gdy dostanie on dużo danych, może zwolnić. Czy istnieje bardziej skuteczny sposób radzenia sobie z tym?
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();
}
}
}
Dzięki za odpowiedź. Naprawdę zapomniałem wspomnieć, że muszę również pogrupować według poziomu napisów. Więc dodałem to. Udało mi się sprawić, aby twoje rozwiązanie działało, ale mam problem. Przejrzyj moją zmianę powyżej. – Linger