我有一个查询,该查询返回日期范围内的事件列表。
string EOOmessage = "";[enter image description here][2]
string eventText = "";
DateTime js = DateTime.Now;
DateTime je = DateTime.Now;
var itCompareDay = (from h in db.DailyGPSTables
where (h.EventDateTime >= startDate
&& h.EventDateTime <= endDate)
select h).ToList();
我想检查每个事件的时间以确保其顺序正确。例如,JE(作业结束)不能早于JS(作业开始)。我已经尝试了很多方法,但这是我的最新方法。它会正确检查匹配的JE标签,但不会说明它在哪一天。
int rowNumber = -1;
foreach (DailyGPSTable e in itCompareDay)
{
if (e.EventType == "JS")
{
js = e.EventDateTime.Value;
}
if (e.EventType == "JE")
{
je = e.EventDateTime.Value;
}
if (je < js)
{
EOOmessage = " On " + e.EventDateTime.Value.ToShortDateString() + " Job end is before Job Start " + eventText;
errorList.Add(EOOmessage);
errorListRow.Add(rowNumber);
}
rowNumber = rowNumber + 1;
}
是否有一种方法可以检查每天是否发生了乱序事件,如果发现,则报告是否不进行第二天的工作?
答案 0 :(得分:1)
使用一种扩展方法,该扩展方法根据我的扩展方法按对进行扫描,并按名为GroupByWhile
的测试对(或假)进行分组扫描:
public static class IEnumerableExt {
// TKey combineFn((TKey Key, T Value) PrevKeyItem, T curItem):
// PrevKeyItem.Key = Previous Key
// PrevKeyItem.Value = Previous Item
// curItem = Current Item
// returns new Key
public static IEnumerable<(TKey Key, T Value)> ScanPair<T, TKey>(this IEnumerable<T> src, TKey seedKey, Func<(TKey Key, T Value), T, TKey> combineFn) {
using (var srce = src.GetEnumerator()) {
if (srce.MoveNext()) {
var prevkv = (seedKey, srce.Current);
while (srce.MoveNext()) {
yield return prevkv;
prevkv = (combineFn(prevkv, srce.Current), srce.Current);
}
yield return prevkv;
}
}
}
// bool testFn(T prevItem, T curItem)
// returns groups by sequential matching bool
public static IEnumerable<IGrouping<int, T>> GroupByWhile<T>(this IEnumerable<T> src, Func<T, T, bool> testFn) =>
src.ScanPair(1, (kvp, cur) => testFn(kvp.Value, cur) ? kvp.Key : kvp.Key + 1)
.GroupBy(kvp => kvp.Key, kvp => kvp.Value);
}
您可以选择按EventDateTime
排序的有趣事件类型(JS / JE),然后按JS
然后按JE
分组,并排除匹配对:
var itCompareDay = (from h in db.DailyGPSTables
where (h.EventDateTime >= startDate
&& h.EventDateTime <= endDate)
orderby h.EventDateTime
select h).ToList();
var errEvents = itCompareDay
.Select((ev, rowNum) => new { ev.EventType, ev.EventDateTime, rowNum })
.Where(cd => cd.EventType == "JS" || cd.EventType == "JE")
.GroupByWhile((pd, cd) => pd.EventType == "JS" && cd.EventType == "JE" && pd.EventDateTime.Date == cd.EventDateTime.Date)
.Where(cdg => cdg.Count() != 2)
.SelectMany(cdg => cdg.Select(cd => new { cd.rowNum, ErrMsg = cd.EventType == "JE" ? "JE without preceding JS" : "JS without following JE" }));
请注意,rowNum
是基于0的,但是如果需要,您可以在第一个Select
中添加1。