LINQ选择记录间隔X分钟

本文关键字:分钟 选择 记录 LINQ | 更新日期: 2023-09-27 17:49:41

我有一个简单的表,用于跟踪条目日期。我想选择间隔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();
}

LINQ选择记录间隔X分钟

这是一个快速实现你所要求的,一个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);

您可以使用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;
}

如前所述,这可以通过迭代轻松实现。然而,如果你真的必须处理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();