LINQ选择记录X分钟

时间:2014-03-11 12:57:29

标签: c# sql linq

我有一个简单的表来跟踪录入日期。我想选择相隔X分钟的记录。

IMAGE_LOCATION  IMAGE DATE
============== =============
2227.jpg    08/03/2014 22:27:47
2228.jpg    08/03/2014 22:28:48
2229.jpg    08/03/2014 22:59:49
2230.jpg    08/03/2014 23:12:50
2231.jpg    08/03/2014 23:29:49

从上面的示例中,我希望查询返回至少相隔X分钟的项目,比方说30分钟。所以从上面的列表2227.jpg,2229.jpg和2231.jpg将只返回。

这是我到目前为止只返回最新图像,但是我需要最新的图像,但记录之间至少相隔30分钟。

using (var db = new GibFrontierEntities())
{
    var result = (from u in db.CCTV_IMAGES.OrderByDescending(u => u.ImageDate)
                  select u).Take(rows);
    return result.ToList();
}

3 个答案:

答案 0 :(得分:1)

这是一个快速尝试,以实现您所要求的,LINQ解决方案(在.NET 4中测试和工作):

var list = db.CCTV_IMAGES.OrderByDescending(u => u.ImageDate);
return list.Where((d, i) =>
        {
            //Look ahead to compare against the next if it exists.
            if (list.ElementAtOrDefault(i + 1) != null)
            {
                return d.ImageDate.Subtract(list.ElementAtOrDefault(i + 1).ImageDate).TotalMinutes > 30;
            }

            //Look behind to compare against the previous if this is the last item in the list.
            if (list.ElementAtOrDefault(i - 1) != null)
            {
                return list.ElementAtOrDefault(i - 1).ImageDate.Subtract(d.ImageDate).TotalMinutes > 30;
            }

            return false;
        }).ToList();

每条评论和更清晰的要求定义:

因为您在下面的评论中说过,您每分钟只有一项,并且您之前曾声明您需要将它们分开至少 30分钟,您是否会考虑将逻辑简化为每30分钟一次列表中的项目?

return list.Where((d, i) => i % 30 == 0);

答案 1 :(得分:0)

您可以使用SelectMany来实现您的目标:

using (var db = new GibFrontierEntities())
{
    var images = db.CCTV_IMAGES;
    var result = images
        .SelectMany(i => images,
            (first, second) => new { First = first, Second = second })
        .Where(i => i.First != i.Second)
        .Where(i => Math.Abs(
            EntityFunctions
                .DiffMinutes(i.First.ImageDate, i.Second.ImageDate)) >= 30)
        .Select(i => i.First)
        .Distinct()
        .OrderByDescending(i => i.ImageDate)
        .Take(rows)
        .ToList();
    return result;
}

答案 2 :(得分:-1)

如上所述,这可以通过迭代轻松实现。但是,你真的需要处理LINQ表达式,这里有一个快速而又脏的样本,它将返回相隔30分钟的日期:

List<DateTime> dateLlist = new List<DateTime>();

        dateLlist.Add(new DateTime(2014, 1, 1, 1, 0, 0, 0));
        dateLlist.Add(new DateTime(2014, 1, 1, 1, 10, 0, 0));
        dateLlist.Add(new DateTime(2014, 1, 1, 1, 45, 0, 0));

        DateTime previousTime = new DateTime();
        bool shouldAdd = false;
        List<DateTime> newList = dateLlist.Where(x =>
        {
            shouldAdd = (previousTime == DateTime.MinValue || previousTime.AddMinutes(30) < x);
            previousTime = x;
            return shouldAdd;
        }).ToList();