LINQ选择每个匹配结果的下一条记录

时间:2016-04-13 09:10:30

标签: c# linq linq-to-sql

我有将测量结果保存到单个表中的对象。我想知道一个物体在一段时间内处于特定状态的时间。

因此,除了获取想要状态的记录之外,我还需要将它与从同一对象进行的下一次测量配对,以计算它们之间的时间。

我想出了这个怪物:

// Get the the object entry from Database
MeasuredObject object1;
try
{
   object1 = (MeasuredObject)(from getObject in db.MeasuredObject where wantedObject.Id.Equals(getObject.Id) select getObject).Single();
}
catch (System.ArgumentNullException e)
{
   throw new System.ArgumentException("Object does not exist", "wantedObject", e);
}

// Get every measurement which matches the state in the time period and the next measurement from it
var pairs = (from m in object1.Measurements
             join nextM in object1.Measurements
             on (from next in object1.Measurements where (m.Id < next.Id) select next.Id).Min() equals nextM.Id
             where 'm is in time period and has required state'
             select new { meas = m, next = nextM });

我会说这似乎不是很有效,特别是当我使用Compact Edition 3.5时。

有没有办法通过m导航到下一个测量,或者我可以通过Id以某种方式使用orderby或group来选择下一个?或者甚至使join子句更简单?

1 个答案:

答案 0 :(得分:2)

从发布的代码看起来就像你正在使用内存集合。如果这是真的,那么以下就足够了:

var items = (from m in object1.Measurements
             where 'm is in time period and has required state'
             orderby m.Id
             select m)
            .ToList();

var pairs = items.Select((item, index) => new
            {
                meas = item,
                next = index + 1 < items.Count ? items[index + 1] : null
            }); 

编辑:上述内容与您的代码不完全相同,因为它会在配对项目之前应用过滤器。精确优化的等价物将是这样的:

var items = object1.Measurements.OrderBy(m => m.Id).ToList();

var pairs = items.Select((item, index) => new
            {
                meas = item,
                next = index + 1 < items.Count ? items[index + 1] : null
            })
            .Where(pair => 'pair.meas is in time period and has required state');