比方說,我有一個代表在某個時間值的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