【问题标题】:Table aggregation using linq (calculate Average value)使用 linq 进行表聚合(计算平均值)
【发布时间】:2018-11-16 04:56:46
【问题描述】:

如何使用 linq 查询聚合下表

Date                tagname                                 value
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(4)   54.73497
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(5)   3.417564
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(4)   94.82829
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(4)   15.08091
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(5)   3.6422
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(4)   5.078211
06-06-2018 14:15:00 Poll.Registers Block 0.310-PT-304_(4)   68.00956
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(5)   94.6864
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   32.43211
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   65.16206
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(5)   81.18947
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   4.419947
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   95.77668
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(5)   10.43907
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   79.12902
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   62.20364
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(5)   97.43433
06-06-2018 14:30:00 Poll.Registers Block 0.310-PT-304_(4)   25.74978
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(5)   50.49747
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(4)   65.33123
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(4)   18.90912
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(5)   55.9916
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(4)   23.86106
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(4)   18.72116
06-06-2018 14:45:00 Poll.Registers Block 0.310-PT-304_(5)   0.06596069

预期的结果应该是这样的

每个时隙只有不同的标记名,该时隙具有平均值,

例如 输出应该是

06-06-2018 14:15:00  Poll.Register Block 0.310-PT-304(4) "Value should be avg"
06-06-2018 14:15:00  Poll.Register Block 0.310-PT-304(5) "Value should be avg"
06-06-2018 14:30:00  Poll.Register Block 0.310-PT-304(4) "Value should be avg"
06-06-2018 14:30:00  Poll.Register Block 0.310-PT-304(5) "Value should be avg"
06-06-2018 14:45:00  Poll.Register Block 0.310-PT-304(4) "Value should be avg"
06-06-2018 14:45:00  Poll.Register Block 0.310-PT-304(5) "Value should be avg"

--- 编辑 -- 这些是我尝试过的几个查询..

var g = (from x in ObjEntities.TagDataValues
                             where x.ValueDateTime >= FromDate && x.ValueDateTime <= EndDate && MachineName.Contains(x.MachineName) && ServerName.Contains(x.ServerName) && Tags.Contains(x.TagName)

                             select new
                             {
                                 TagName = x.TagName,
                                 MachineName = x.MachineName,
                                 ServerName = x.ServerName,
                                 TagValue = x.TagValue,
                                 DtTime = x.ValueDateTime
                             }).ToList().GroupBy(cd => new
                             {
                                 date = cd.DtTime.AddSeconds(-cd.DtTime.Second).AddMinutes(-cd.DtTime.Minute % 15),
                                 tagname = cd.TagName,
                                 tagvalue = cd.TagValue
                             }).ToList().Select(o => new
                             {
                                 Date = o.Key.date,
                                 tagname = o.Key.tagname,
                                 value = o.Key.tagvalue
                             }).ToList().GroupBy(tr => tr.tagname).Select(x => new {
                                TagName = x.Key,
                                Value = x.Average(gf => gf.value),
                                Date = x.Select(gf => gf.Date).Distinct()
                             }).ToList();





var g = (from x in ObjEntities.TagDataValues
                             where x.ValueDateTime >= FromDate && x.ValueDateTime <= EndDate && MachineName.Contains(x.MachineName) && ServerName.Contains(x.ServerName) && Tags.Contains(x.TagName)

                             select new
                             {
                                 TagName = x.TagName,
                                 MachineName = x.MachineName,
                                 ServerName = x.ServerName,
                                 TagValue = x.TagValue,
                                 DtTime = x.ValueDateTime
                             }).ToList().GroupBy(cd => new
                             {
                                 date = cd.DtTime.AddSeconds(-cd.DtTime.Second).AddMinutes(-cd.DtTime.Minute % 15),
                                 tagname = cd.TagName,
                                 tagvalue = cd.TagValue
                             }).ToList().Select(o => new
                             {
                                 Date = o.Key.date,
                                 tagname = o.Key.tagname,
                                 value = o.Key.tagvalue
                             }).ToList().GroupBy(tr => new {
                                TagName = tr.tagname,
                                DateTime = tr.Date
                             } ).Select(x => new {
                                TagName = x.Key,
                                Value = x.Average(gf => gf.value),
                                Date = x.Key.DateTime
                             }).ToList();

我是 LINQ 新手,所以无法获得正确的结果..

我已经写了同样的sql查询,它给出了完美的结果

declare @StartDate DateTime = CAST('06/06/2018 14:26:56' AS datetime) declare @EndDate DateTime = CAST('06/06/2018 14:32:56' AS datetime) SELECT CONVERT(nvarchar, ValueDateTime, 113) as MINUTE , avg(TagDataValue.TagValue) Value, TagName FROM TagDataValue WHERE ValueDateTime >=  @StartDate AND ValueDateTime <= @EndDate and TagName in ('Poll.Registers Block 0.310-PT-304_(4)','Poll.Registers Block
0.310-PT-304_(5)') GROUP BY CONVERT(nvarchar, ValueDateTime, 113) , TagName

这个查询给出了完美的结果,但是由于代码在 linq 中不能使用这个查询或不能转换它。

任何帮助请..

【问题讨论】:

  • 你试过了吗?
  • @DavidG 是的,我参考blog.pixentia.com/aggregate-data-using-entity-framework 尝试了几个查询,还尝试将值添加到forloop 但无法获取值.. :(
  • 然后向我们展示您尝试过的内容以及无法使用的内容。恐怕这不是一个代码编写服务。
  • @DavidG 请查看编辑部分。这些是我尝试过的一些问题。但不能得到结果:(
  • @DavidG 也尝试使用带有引用 c-sharpcorner.com/UploadFile/3d39b4/… 的 Group 函数,但它将列表中的所有标签分组并且没有给出日期时间.. :( 有点卡住了

标签: linq entity-framework-6 linq-to-entities aggregate aggregation


【解决方案1】:

按日期时间分组总是很棘手,因为 C# 中可用的许多函数在生成 SQL 代码时不可用,并且可能会导致问题。

由于我无法重现您的环境,因此我创建了一些仅基于 linq 的示例。您可能必须使用 TruncateTime 重新创建,以便它在数据库级别完全运行。

var g = entityList
                .Where(x => x.ValueDateTime >= FromDate && x.ValueDateTime <= ToDate && MachineNames.Contains(x.MachineName))
                .Select(x => new
                {
                    quarterDateTime = x.ValueDateTime
                                       .AddSeconds(-x.ValueDateTime.Second)
                                       .AddMinutes(-x.ValueDateTime.Minute % 15),
                    x.MachineName,
                    x.Value
                })
                .GroupBy( x => new { x.quarterDateTime, x.MachineName })
                .Select( x => new {  x.Key.quarterDateTime, x.Key.MachineName, AverageValue = x.Average(p => p.Value) })
                .OrderBy( x => x.quarterDateTime )
                .ToList();

我会说,可能第一个 Select 和 GroupBy 可以合并,但为了更好的可读性,我分开了。

有关 TruncateTime 的更多信息,请参阅this

【讨论】:

  • 刚刚更新了答案。我已经编写了一些示例,使用类似的类等。但没有数据库。它正在按照您的要求工作。让我知道是否可行以及您是否需要其余代码(与答案无关,但以防万一您需要)。
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 2012-10-11
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 2016-02-15
  • 2020-06-26
  • 2011-02-12
相关资源
最近更新 更多