我今天第一次陷入某些linq查询,我正在努力解决一些比较复杂的问题。我正在构建一个查询来从表中提取数据以构建图形。我感兴趣的表格列是 Id ,时间和值。
用户将选择开始时间,结束时间和要绘制的间隔(点)数。值列将针对每个间隔进行平均。
我可以使用每个间隔的linq请求执行此操作,但我正在尝试在一个查询中编写它,所以我只需要去一次数据库。
到目前为止,我有:
var timeSpan = endTime.Subtract(startTime);
var intervalInSeconds = timeSpan.TotalSeconds / intervals;
var wattList = (from t in _table
where t.Id == id
&& t.Time >= startTime
&& t.Time <= endTime
group t by intervalInSeconds // This is the bit I'm struggling with
into g
orderby g.Key
select g.Average(a => a.Value))
).ToList();
欢迎任何有关时间范围分组的帮助。
答案 0 :(得分:1)
我自己也是这样做的,因为你描述的情况完全相同。
对于速度,修改数据库的datapoints表以包含基于整数的时间列SecondsSince2000
,然后在我的LINQ to SQL查询中使用该值。 SecondsSince2000
是计算列,定义为:
datediff(second, dateadd(month,1200,0), DataPointTimeColumn) PERSISTED
其中DataPointTimeColumn
是存储数据点时间的列的名称。魔术函数dateadd(month,1200,0)
在午夜返回2000-01-01,因此该列存储自该时间以来的秒数。
然后,LINQ to SQL查询变得更加简单,更快:
int timeSlotInSeconds = 60;
var wattList =
(from t in _table
where t.Id == id
&& t.Time >= startTime
&& t.Time <= endTime
group t by t.SecondsSince2000 - (t.SecondsSince2000 % timeSlotInSeconds)
into g
orderby g.Key
select g.Average(a => a.Value))).ToList();
如果您无法修改数据库,您仍然可以执行此操作:
var baseTime = new DateTime(2000, 1, 1);
var wattList =
(from t in _table
where t.Id == id
&& t.Time >= startTime
&& t.Time <= endTime
let secondsSince2000 = (int)(t.Time- baseTime).TotalSeconds
group t by secondsSince2000 - (secondsSince2000 % timeSlotInSeconds)
into g
orderby g.Key
select g.Average(a => a.Value))).ToList();
查询会慢得多。
答案 1 :(得分:0)
看看我刚才写的这个例子。这听起来像你要做的,但我不确定它是用SQL还是.NET进行分组。
http://mikeinmadison.wordpress.com/2008/03/12/datetimeround/
答案 2 :(得分:0)
也许你可以这样做:
var wattList = (from t in _table
where t.Id == id
&& t.Time >= startTime
&& t.Time <= endTime
).GroupBy(x => (int) ((x.Time - startTime).TotalSeconds / intervalInSeconds))
.Select(grp => grp.Average(x => x.Value));