如何在多个 Linq IQueryable 上执行 sql 联合
How can I do an sql Union on multiple Linq IQueryables
我正在做一个项目,我想用日志数据制作图表。
因此,我已将我的日志数据加载到我的 sql 服务器中,并找到了产生我需要的结果的查询。每个日志条目包含每 2 秒的测量值。
SELECT '7am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 07:00:00' AND [epochasdate] <= '2018-05-03 08:00:00'
UNION
SELECT '8am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 08:00:00' AND [epochasdate] <= '2018-05-03 09:00:00'
UNION
SELECT '9am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 09:00:00' AND [epochasdate] <= '2018-05-03 10:00:00'
此示例显示了三个时隙以及在此时隙上的一些计算值。
现在我正尝试使用 linq 查询在 C# 中重现此 SQL 结果,因为我想在图表中显示结果。我想出了以下内容:
using (var entity = new DBEntity.Entities())
{
var startDatetime = new DateTime(2018, 05, 03, 7, 0, 0);
var endDatetime = new DateTime(2018, 05, 03, 8, 0, 0);
var firstResult = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, 0) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, 0))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
var secondResult = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, 0) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, 0))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
var finalQuery = CreateEmptyEnumerable(firstResult);
for (var i = 1; i <= 24; i++)
{
var result = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, i) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, i))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
finalQuery = finalQuery.Concat(result);
}
var test1 = firstResult.Concat(secondResult).ToList();
var test2 = finalQuery.ToList();
}
现在变量test1实际上包含了2行我需要的数据。但我希望变量 test2 包含 24 行(1 天)的数据。
但它不包含任何行。
那么,如何连接多个结果变量,然后在 finalQuery 上 运行 ToList()?
编辑:或者如何在循环中使用 concat?
你问的是连接,但你似乎在用它,所以我不确定你需要什么,但是
如果您希望每小时对变量中的 24 条记录进行分组,您可以 运行 按数据的小时进行分组。像这样
var groupedbyhour = entity.M_FC66294.GroupBy(entry => entry.epochasdate.Date.AddHours(entry.epochasdate.Hour))//group by hour
.Select(HourGroup => new
{
TankTemp = HourGroup.Average(x => x.Tanktemperature_C),
Bar = HourGroup.Average(x => x.Pressure_bar),
MinOdo = HourGroup.Min(x => x.Odometer_km),
MaxOdo = HourGroup.Max(x => x.Odometer_km),
epochasdate = HourGroup.Max(x => x.epochasdate.Date.AddHours(x.epochasdate.Hour))
}).ToList();
请记住,epochasdate 现在是小时组,例如 2019/07/30 - 7:00 和 2019/07/30 - 8:00
更新
这是我的完整测试,您可以复制。
public class entry
{
public int Odometer_km;
public DateTime epochasdate;
public int Tanktemperature_C;
public int Pressure_bar;
}
class Program
{
static void Main(string[] args)
{
List<entry> entries = new List<entry>(){
new entry() {epochasdate = new DateTime(2019, 07, 29, 7, 2, 1), Odometer_km = 10, Pressure_bar = 1, Tanktemperature_C = 23},
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 1, 1), Odometer_km = 20, Pressure_bar = 2, Tanktemperature_C = 25 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 3, 1), Odometer_km = 22, Pressure_bar = 2, Tanktemperature_C = 24 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 22, 1), Odometer_km = 25, Pressure_bar = 4, Tanktemperature_C = 22 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 24, 1), Odometer_km = 36, Pressure_bar = 2, Tanktemperature_C = 20 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 21, 1), Odometer_km = 42, Pressure_bar = 3, Tanktemperature_C = 19 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 29, 1), Odometer_km = 50, Pressure_bar = 2, Tanktemperature_C = 21 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 22, 1), Odometer_km = 55, Pressure_bar = 4, Tanktemperature_C = 20 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 52, 1), Odometer_km = 62, Pressure_bar = 2, Tanktemperature_C = 19 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 43, 1), Odometer_km = 80, Pressure_bar = 3, Tanktemperature_C = 17 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 22, 1), Odometer_km = 120, Pressure_bar = 1, Tanktemperature_C = 18 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 12, 1), Odometer_km = 140, Pressure_bar = 3, Tanktemperature_C = 16 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 31, 1), Odometer_km = 156, Pressure_bar = 2, Tanktemperature_C = 17 }
};
var groupedbyhour = entries.GroupBy(entry => entry.epochasdate.Date.AddHours(entry.epochasdate.Hour))//group by hour
.Select(HourGroup => new
{
TankTemp = HourGroup.Average(x => x.Tanktemperature_C),
Bar = HourGroup.Average(x => x.Pressure_bar),
MinOdo = HourGroup.Min(x => x.Odometer_km),
MaxOdo = HourGroup.Max(x => x.Odometer_km),
MeasureTime = HourGroup.Max(x => x.epochasdate.Date.AddHours(x.epochasdate.Hour))
}).ToList();
}
}
如果您的 epochasdate 类型不是日期时间并且由于某种原因无法分组,请使用 .addhour 并将 0 小时添加到它应该 return 您的 groupby 功能可以理解的 DateTime 结果
我正在做一个项目,我想用日志数据制作图表。
因此,我已将我的日志数据加载到我的 sql 服务器中,并找到了产生我需要的结果的查询。每个日志条目包含每 2 秒的测量值。
SELECT '7am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 07:00:00' AND [epochasdate] <= '2018-05-03 08:00:00'
UNION
SELECT '8am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 08:00:00' AND [epochasdate] <= '2018-05-03 09:00:00'
UNION
SELECT '9am' as timeslot, MAX(Odometer_km) - MIN(Odometer_km) as distance, AVG(Tanktemperature_C) tanktemp, AVG(Pressure_bar) avgBar FROM [FC66294]
where [epochasdate] >= '2018-05-03 09:00:00' AND [epochasdate] <= '2018-05-03 10:00:00'
此示例显示了三个时隙以及在此时隙上的一些计算值。
现在我正尝试使用 linq 查询在 C# 中重现此 SQL 结果,因为我想在图表中显示结果。我想出了以下内容:
using (var entity = new DBEntity.Entities())
{
var startDatetime = new DateTime(2018, 05, 03, 7, 0, 0);
var endDatetime = new DateTime(2018, 05, 03, 8, 0, 0);
var firstResult = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, 0) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, 0))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
var secondResult = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, 0) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, 0))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
var finalQuery = CreateEmptyEnumerable(firstResult);
for (var i = 1; i <= 24; i++)
{
var result = entity.M_FC66294
.Where(x => x.epochasdate >= System.Data.Entity.DbFunctions.AddHours(startDatetime, i) && x.epochasdate <= System.Data.Entity.DbFunctions.AddHours(endDatetime, i))
.GroupBy(x => 1)
.Select(g => new {
TankTemp = g.Average(x => x.Tanktemperature_C),
Bar = g.Average(x => x.Pressure_bar),
MinOdo = g.Min(x => x.Odometer_km),
MaxOdo = g.Max(x => x.Odometer_km)
});
finalQuery = finalQuery.Concat(result);
}
var test1 = firstResult.Concat(secondResult).ToList();
var test2 = finalQuery.ToList();
}
现在变量test1实际上包含了2行我需要的数据。但我希望变量 test2 包含 24 行(1 天)的数据。
但它不包含任何行。
那么,如何连接多个结果变量,然后在 finalQuery 上 运行 ToList()?
编辑:或者如何在循环中使用 concat?
你问的是连接,但你似乎在用它,所以我不确定你需要什么,但是
如果您希望每小时对变量中的 24 条记录进行分组,您可以 运行 按数据的小时进行分组。像这样
var groupedbyhour = entity.M_FC66294.GroupBy(entry => entry.epochasdate.Date.AddHours(entry.epochasdate.Hour))//group by hour
.Select(HourGroup => new
{
TankTemp = HourGroup.Average(x => x.Tanktemperature_C),
Bar = HourGroup.Average(x => x.Pressure_bar),
MinOdo = HourGroup.Min(x => x.Odometer_km),
MaxOdo = HourGroup.Max(x => x.Odometer_km),
epochasdate = HourGroup.Max(x => x.epochasdate.Date.AddHours(x.epochasdate.Hour))
}).ToList();
请记住,epochasdate 现在是小时组,例如 2019/07/30 - 7:00 和 2019/07/30 - 8:00
更新
这是我的完整测试,您可以复制。
public class entry
{
public int Odometer_km;
public DateTime epochasdate;
public int Tanktemperature_C;
public int Pressure_bar;
}
class Program
{
static void Main(string[] args)
{
List<entry> entries = new List<entry>(){
new entry() {epochasdate = new DateTime(2019, 07, 29, 7, 2, 1), Odometer_km = 10, Pressure_bar = 1, Tanktemperature_C = 23},
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 1, 1), Odometer_km = 20, Pressure_bar = 2, Tanktemperature_C = 25 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 3, 1), Odometer_km = 22, Pressure_bar = 2, Tanktemperature_C = 24 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 7, 22, 1), Odometer_km = 25, Pressure_bar = 4, Tanktemperature_C = 22 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 24, 1), Odometer_km = 36, Pressure_bar = 2, Tanktemperature_C = 20 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 21, 1), Odometer_km = 42, Pressure_bar = 3, Tanktemperature_C = 19 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 29, 1), Odometer_km = 50, Pressure_bar = 2, Tanktemperature_C = 21 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 22, 1), Odometer_km = 55, Pressure_bar = 4, Tanktemperature_C = 20 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 8, 52, 1), Odometer_km = 62, Pressure_bar = 2, Tanktemperature_C = 19 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 43, 1), Odometer_km = 80, Pressure_bar = 3, Tanktemperature_C = 17 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 22, 1), Odometer_km = 120, Pressure_bar = 1, Tanktemperature_C = 18 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 12, 1), Odometer_km = 140, Pressure_bar = 3, Tanktemperature_C = 16 },
new entry() { epochasdate = new DateTime(2019, 07, 29, 9, 31, 1), Odometer_km = 156, Pressure_bar = 2, Tanktemperature_C = 17 }
};
var groupedbyhour = entries.GroupBy(entry => entry.epochasdate.Date.AddHours(entry.epochasdate.Hour))//group by hour
.Select(HourGroup => new
{
TankTemp = HourGroup.Average(x => x.Tanktemperature_C),
Bar = HourGroup.Average(x => x.Pressure_bar),
MinOdo = HourGroup.Min(x => x.Odometer_km),
MaxOdo = HourGroup.Max(x => x.Odometer_km),
MeasureTime = HourGroup.Max(x => x.epochasdate.Date.AddHours(x.epochasdate.Hour))
}).ToList();
}
}
如果您的 epochasdate 类型不是日期时间并且由于某种原因无法分组,请使用 .addhour 并将 0 小时添加到它应该 return 您的 groupby 功能可以理解的 DateTime 结果