比方说,我有一个代表在某个时间值的EF实体类:LINQ - 过滤,分组和获得最小值和最大值
public class Point
{
public DateTime DT {get; set;}
public decimal Value {get; set;}
}
我也代表某个时间段的一类:
public class Period
{
public DateTime Begin {get; set;}
public DateTime End {get; set;}
}
然后我有Period
的数组,可以包含一些特定的时间段,让我们说,它看起来像(Period
对象总是按升序排列数组中):
var periodSlices = new Period []
{
new Period { Begin = new DateTime(2016, 10, 1), End = new DateTime(2016, 10, 15)},
new Period { Begin = new DateTime(2016, 10, 16), End = new DateTime(2016, 10, 20)},
new Period { Begin = new DateTime(2016, 10, 21), End = new DateTime(2016, 12, 30)}
};
现在,使用LINQ to SQL如何写在每个的periodSlices
这将有最古老的(分)滤除和组Point
的查询和最新的(最大)值,所以在这个例子场景中的结果应该有一组3个最小和最大点(当然如果有的话)。
所以我需要的结果就像IQueryable<Period, IEnumerable<Point>>
。
现在我做这种方式,但性能不是最大:
using (var context = new EfDbContext())
{
var periodBegin = periodSlices[0].Begin;
var periodEnd = periodSlices[periodSlices.Length - 1].End;
var dbPoints = context.Points.Where(p => p.DT >= periodBegin && p.DT <= periodEnd).ToArray();
foreach (var slice in periodSlices)
{
var points = dbPoints.Where(p => p.DT >= slice.Begin && p.DT <= slice.End);
if (points.Any())
{
var latestValue = points.MaxBy(u => u.DT).Value;
var earliestValue = points.MinBy(u => u.DT).Value;
}
}
}
性能是至关重要的(速度越快越好,因为我需要过滤掉和组〜点100K)。
如果在你的集合项目很多,你可以使用Parallel.ForEach,它可以提高速度 – Ferus7
查询这个复杂的是不理想的EF,因为它是不可能的框架,以生成优化的查询此复杂。你可以做两件事:1)创建一个你可以用EF调用的存储过程。 2)_Maybe_创建一个视图来查询最小和最大值,但我认为如果你正在寻找3组数据,你很可能需要查询它3次,使它不理想。 – krillgar
在你的例子中,你为什么重复'periodSlices'?无论“切片”的值如何,您只需运行相同的代码3次。 – Rotem