![](/img/trans.png)
[英]Entity Framwork Core + Linq: How do I get the entire entity that has the max value? Looking for a more elegant solution
[英]Is there a more elegant solution to calculating the Timespan that a certain value is occurring in Entity Framework?
我的问题:我的数据库中有一个名为DevicePropertyUpdates的表。 我们使用此表记录设备中的状态更改。 我需要知道特定模式在指定时间范围内处于活动状态的总时间。
例如,如果模式A从00:00到4:00,模式B从4:00到10:00,模式A从10:00到16:00,模式C从16:00到24:00 。 如果我想知道模式A在一天中处于激活状态的时间,我将00:00到4:00和10:00到16:00加起来,总共得到10个小时。
我当前的代码如下。 非常迭代,我相信它将迫使实体框架在整个日期范围内实现所有这些模式。 我正在寻找一种更优雅的解决方案,以提高我的问题解决能力并编写更简洁的代码。 我希望我只是想念一些可以学到的东西。 我考虑的想法是.Zip,.GroupBy或某种联接来发现差异,但是我想不出任何有用的方法。
架构师更喜欢使用实体框架方法。 DevicePropertyUpdates表具有以下结构。
时间戳记-日期时间
StringValue-varchar(最大值)
名称-varchar(100)
示例SQL
第1行:“ OperatingMode”,“ A”,“ 2014/7/1 1:00:00”
第2行:“ OperatingMode”,“ A”,“ 2014/7/1 2:00:00”
第3行:“ OperatingMode”,“ B”,“ 2014年7月1日2:15:00”
第4行:“ OperatingMode”,“ A”,“ 2014年7月1日3:33:00”
using (Container container = ContextFactory.CreateInstance())
{
IEnumerable<Model.DevicePropertyUpdate> updates =
container.DevicePropertyUpdates.Where(
dpu => dpu.Name == "OperatingMode" && dpu.Timestamp <= endTime && dpu.Timestamp >= startTime);
TimeSpan totalTime = TimeSpan.Zero;
DateTime? start = null;
foreach (var update in updates)
{
if (update.StringValue == operatingMode)
{
if (!start.HasValue)
{
start = update.Timestamp;
}
}
else
{
if (start.HasValue)
{
totalTime += update.Timestamp - startTime;
start = null;
}
}
}
//Include edge case if matching operating mode was the last to occur in the time range.
if (start.HasValue)
{
totalTime += endTime - startTime;
}
return totalTime;
}
您可以总结从时间戳到结束时间的所有“打开时间”。 然后将所有空闲时间相加并求和。 这将需要两个SQL语句和一个遵循一些规则的结果集。 它必须以ON开头,以IDLE结尾,每个ON必须有一个对应的IDLE。
| ON IDLE ON IDLE ON IDLE |
------------------------------------------------------------------
-------------------------------------------------
-------------------------
----------------------------------------------------------
------------------------------------------
----------------
您的Linq看起来像这样。
using (var db = new TestContext()) {
DateTime startDate = new DateTime(2014,05,01), endDate = new DateTime(2014,06,1);
var baseQuery = db.DevicePropertyUpdates
.Where(p => p.TimeStamp >= startDate && p.TimeStamp < endDate)
.Where(p => p.Name == "OperatingMode");
var OnSum = baseQuery.Where(p => p.StringValue == "ON")
.Sum(p => SqlFunctions.DateDiff("ss",p.TimeStamp, endDate));
var IdleSum = baseQuery.Where(p => p.StringValue == "IDLE")
.Sum(p => SqlFunctions.DateDiff("ss", p.TimeStamp,endDate));
var duration = TimeSpan.FromSeconds(OnSum.Value - IdleSum.Value);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.