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