实体框架:在时间间隔优化之间应用操作

问题描述 投票:1回答:1

问题定义:我有一个包含数百万条目的数据库表。该表使用以下列定义:Date,Value和NumberOfEvents。我需要在几个时间间隔之间获取数据,并对每个间隔的所有返回记录应用函数(Sum,Average,Max,Min)。

当前解决方案

   List<SingleSeries> series = new List<SingleSeries>();
            //Iterate intervals
            for (int i = 0; i < intervals.Count(); i++)
            {
                if (i == 0)
                {
                }
                if (i + 1 < intervals.Count())
                {
                    //Get database entries between interval
                    var validKpis = kpis.Where(x => x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));
                    //Apply calc operation (SUM; AVG; MAX;MIN)
                    var result= CalcOperations.Calculate(calcOperation, validKpis);
                    //Add result to results array
                    series.Add(new SingleSeries()
                    {
                        Value = result,
                        Name = DateOperations.ConvertToMilliseconds(intervals.ElementAt(i + 1)).ToString()
                    });
                };
            }
            return series;

当前问题:目前此函数对数据库执行N个查询,其中N = intervals.Count()/ 2。我想它只做一个查询,但我不知道如何使用区间数组聚合每个区间的值,并对其应用计算操作。建议吗?

c# time entity-framework-core intervals
1个回答
0
投票

您需要构建单个查询,该查询将获取所有间隔的结果,然后循环显示间隔以将结果集拆分为每个特定间隔的结果集。

它的代码更多一些,但更有效地使用数据库请求。

这是一个粗略的片段,展示了上述内容 - 请注意,我没有对此进行测试 - 它只是为了让您具体了解如何使用单个查询来执行此操作。

        List<SingleSeries> series = new List<SingleSeries>();
        var kpiQuery = kpis;

        //Iterate intervals and build a single query to retrieve all of them
        for (int i = 0; i < intervals.Count(); i++)
        {
            if (i + 1 < intervals.Count())
            {
                // add each target interval sequentially - without running the query yet
                kpiQuery = kpiQuery.Where(x => x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));
            }
        }

        var validKpis = kpiQuery.ToList(); // now get all database results in a single transaction

        //Iterate the intervals again, this time to split the combined results that are now in memory
        for (int i = 0; i < intervals.Count(); i++)
        {
            if (i + 1 < intervals.Count())
            {
                //select only the results applicable to the current interval
                var kpisInThisInterval = validKpis.Where(x =>
                    x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));

                //Apply calc operation (SUM; AVG; MAX;MIN)
                var result = CalcOperations.Calculate(calcOperation, kpisInThisInterval);
                //Add result to results array
                series.Add(new SingleSeries()
                {
                    Value = result,
                    Name = DateOperations.ConvertToMilliseconds(intervals.ElementAt(i + 1)).ToString()
                });
            }
        }

        return series;
© www.soinside.com 2019 - 2024. All rights reserved.