如何在多个 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 结果