如何在LINQ中创建一个过滤器,其中查询仅将两个后续行组合在一起,如果它们的Level列由一个列提升。
这就是我现在所拥有的:
var alert = db.Logs.OrderBy(u => u.Time).GroupBy(r => r.EquipmentNr).Where(s => s.Count() > 1);
然而,它不会找到那些在Level列中不同的行,并且它们必须随着时间的推移而不同。必须有彼此相邻的行,按时间排序。
或者我应该手动创建分组类,运行我已经拥有的查询并添加是否找到它们?
public class Log
{
public int Id { get; set; }
public DateTime Time { get; set; }
public Shift Shift { get; set; }
public int EquipmentNr { get; set; }
public int OrderNr { get; set; }
public bool SupervisorCalled { get; set; }
public string Issue { get; set; }
public string Repairs { get; set; }
public string Responsible { get; set; }
public Level Level { get; set; }
}
答案 0 :(得分:0)
大多数情况下,对于顺序处理,列表中的元素以某种方式相关,经典foreach
比LINQ好得多。通常它甚至不能由LINQ完成。但是,在这种情况下,只需要比较连续的元素,因此可以使用Aggregate
。
分组条件是:level(n) - level(n-1) = 1
。因此,我们应该为满足此条件的列表中的每个元素添加相同的分组键。这是一种方法(使用Linqpad)。每个元素都存储在Tuple
中,其中Item1
是分组键。然后按这些键对元组进行分组:
void Main()
{
var list = new List<Equipment>
{
new Equipment{Level = 11},
new Equipment{Level = 1},
new Equipment{Level = 18},
new Equipment{Level = 0},
new Equipment{Level = 6},
new Equipment{Level = 4},
new Equipment{Level = 5},
new Equipment{Level = 20},
new Equipment{Level = 9},
new Equipment{Level = 14},
new Equipment{Level = 12},
new Equipment{Level = 17},
new Equipment{Level = 2},
new Equipment{Level = 13},
new Equipment{Level = 15},
};
list.OrderBy(eq => eq.Level)
.Aggregate
(
new List<Tuple<int,Equipment>>(), // Seed the list of tuples
(tuples,eq) =>
{
// The grouping condition: compare to the previous item
// (if present) and use its Level as grouping key if the
// condition is met.
var key = tuples.Any()
&& eq.Level - tuples.Last().Item2.Level == 1
? tuples.Last().Item1
: eq.Level;
tuples.Add(Tuple.Create(key, eq));
return tuples;
},
tuples => tuples.GroupBy (tuple => tuple.Item1)
// Done! Now just a Select for display
).Select
(tupleGroup =>
new {
tupleGroup.Key,
Numbers = string.Join(",", tupleGroup
.Select(e => e.Item2.Level))
}
). Dump();
}
// Define other methods and classes here
class Equipment
{
public int Level { get; set; }
}
输出:
Key Numbers
--- --------------
0 0,1,2
4 4,5,6
9 9
11 11,12,13,14,15
17 17,18
20 20