我有一个数据表,其中填充了有关PLC警报状态已更改(升高=开,已解决=关)的记录。每个记录包含Date,Hour,Zone,AlarmCode,AlarmState('O'|'C')。
给定“ O”(ON)列表,如何使用linq查找下一个对应的“ C”(OFF)状态(带有相同防区和警报代码的obv)的“最近”状态? 另外,最好提供持续时间和仍打开警报(“ O”而不用“ C”)或关闭警报而不用打开(因为“ O”不在所选的当前间隔上)。
我在这里发布了我现在正在使用的代码(非常基本)
private void CalculateAlarms()
{
DataTable dtOn, dtOff;
DateTime dON, dOFF;
dtOn = dtAlr.AsEnumerable().Where(x => x.Field<string>("STATE").Equals("O")).CopyToDataTable(); //ALREADY ORDERED BY DATE,HOUR
dtOff = dtAlr.AsEnumerable().Where(x => x.Field<string>("STATE").Equals("C")).CopyToDataTable(); //ALREADY ORDERED BY DATE,HOUR
dtOn.Columns.Add("Min", typeof(TimeSpan));
dtOn.Columns.Add("HourOff", typeof(DateTime));
foreach (DataRow rowON in dtOn.Rows)
{
dON = rowON["DATETIMEALR"];
foreach (DataRow rowOff in dtOff.Rows)
{
dOFF = rowOFF["DATETIMEALR"];
if (rowON["ALRCOD"].Equals(rowOff["ALRCOD"]) && rowON["ALRZONE"].Equals(rowOff["ALRZONE"]) && DateTime.Compare(dON, dOFF) <= 0)
{
rowON["HourOff"] = dOFF;
rowON["Min"] = dOFF.Subtract(dON);
dtOff.Rows.Remove(rowOff);
break;
}
}
}
DataTable toCopy;
toCopy = dtOn.AsEnumerable().Where(x => x.IsNull("HourOff"));
DataTable OnWithoutOFF = toCopy.Any() ? toCopy.CopyToDataTable() : new DataTable();
toCopy = dtOn.AsEnumerable().Where(x => !x.IsNull("HourOff"));
dtOn = toCopy.Any() ? toCopy.CopyToDataTable() : new DataTable();
// So here i have OnWithoutOFF => Alarms opened but not closed , dtOn => Alarms opened and closed , dtOff => Alarms closed but not opened
}