每天遍历linq查询结果以检查条件

时间:2018-11-09 17:31:34

标签: c# asp.net linq entity-framework-6

我有一个查询,该查询返回日期范围内的事件列表。

enter image description here

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;
}

是否有一种方法可以检查每天是否发生了乱序事件,如果发现,则报告是否不进行第二天的工作?

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。