Tengo datos que se graban cada 15 minutos en las tablas PowerStringHistorys y PowerCombinerHistorys. Soy nuevo en LINQ y estoy tratando de descubrir cómo crear una consulta que agrupe mis datos por hora y para esa hora el promedio actual. Aquí es lo que tengo hasta ahoraAgrupar por hora usando 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
};
Ahora necesito al grupo por el combinador y la hora, así que puede promediar la corriente y obtener el kwh para cada combinador para cada hora del intervalo de fechas especificado.
I necesidad de aplicar esta fórmula simple en la consulta de algún modo: (vatios por hora promedio)/1000 = Kwh
Entonces, ¿qué voy a terminar con algo como lo de abajo. Cualquier ayuda sería muy apreciada.
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
EDITAR
anterior fue mi pregunta original. Después de trabajar con las dos sugerencias que recibí, terminé con el código que se muestra a continuación. Ahora mismo estoy devolviendo las fechas y el total de Kwh a la vista. Planeo lanzar la lista stringGroupedKwhlist en un HighChart para que el usuario vea y arroje los primeros resultados de la consulta Q a una grilla de Telerik para que el usuario filtre/ordene/agrupe para que pueda trabajar con los detalles. Si bien el código funciona y produce el resultado que estoy esperando, no estoy seguro de que sea eficiente. Como tengo que pasar por el uso de un foreach, supongo que una vez que obtiene una gran cantidad de datos podría ralentizarse. ¿Hay una manera más eficiente de manejar esto?
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();
}
}
}
Gracias por la respuesta. De hecho, olvidé mencionar que también necesitaba agruparme por el nivel de cuerda. Entonces agregué eso. Logré que tu solución funcionara; sin embargo, tengo una preocupación. Por favor, revisa mi edición anterior. – Linger