每天遍历linq查询结果以检查条件 [英] Iterate through linq query results by day to check conditions
问题描述
我有一个查询,该查询返回日期范围内的事件列表.
I have a query that returns a list of events in a date range.
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标签,但不会说明它在哪一天.
I want to check the time for each event to make sure its in the proper sequence. For example JE(Job End) cannot be before JS(Job Start). I have tried many ways but this is my latest. It checks for a matching JE tag correctly but it doesn't account for which day it is in.
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;
}
有没有一种方法可以每天检查不按顺序发生的事件,如果发现则报告到第二天是否不发生?
Is there a way to check each day for out of sequence events and if found report them if not go to the next day?
推荐答案
使用一种扩展方法,该扩展方法根据我的扩展方法按对进行扫描,并按顺序扫描并在测试为true(或false)的分组时将其分组为GroupByWhile
:
Using an extension method that scans sequentially and groups while a test is true (or false) named GroupByWhile
based on my extension method for scanning by pairs:
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
分组,并抛出匹配对:
You can select out the interesting event types (JS/JE) ordered by EventDateTime
and then group by JS
followed by JE
and throw out matching pairs:
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.
Note that rowNum
is 0 based but you could add 1 in the first Select
if desired.
这篇关于每天遍历linq查询结果以检查条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!