using System.Data;
namespace Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess;
///
/// S8 监控数据的 canonical 结果集。
///
/// 承担原先 的两个职责:承载行、回答"结果集是否含某列"。
/// 后者是 evaluator canonical→params 回退逻辑的输入,语义必须与 DataTable.Columns.Contains 一致
/// (列集合在整个结果集内稳定,因此在结果集层面回答,而不是逐行判断)。
///
public sealed class S8MonitoringRowSet
{
private readonly HashSet _columns;
private S8MonitoringRowSet(IReadOnlyList rows, HashSet columns)
{
Rows = rows;
_columns = columns;
}
/// 结果集行。
public IReadOnlyList Rows { get; }
/// 结果集列名(去重,OrdinalIgnoreCase)。
public IReadOnlyCollection Columns => _columns;
/// 结果集是否包含该列。驱动 evaluator 的 canonical 优先 / params 回退分支。
public bool HasColumn(string? columnName) =>
!string.IsNullOrWhiteSpace(columnName) && _columns.Contains(columnName!);
/// 空结果集。
public static S8MonitoringRowSet Empty { get; } =
new(Array.Empty(), new HashSet(StringComparer.OrdinalIgnoreCase));
/// 由 Legacy SQL / API 取数结果构造。保留全部列,供 payload 落盘与 params 回退使用。
public static S8MonitoringRowSet FromDataTable(DataTable table)
{
var columns = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (DataColumn column in table.Columns)
columns.Add(column.ColumnName);
var rows = new List(table.Rows.Count);
foreach (DataRow row in table.Rows)
rows.Add(S8MonitoringRow.FromDataRow(row));
return new S8MonitoringRowSet(rows, columns);
}
///
/// 由标准 Provider 产出的 canonical 行构造。列集合取所有行键的并集
/// (标准 Provider 各行结构一致,取并集可容忍可选列在部分行缺失)。
///
public static S8MonitoringRowSet FromRows(IEnumerable rows)
{
var list = rows as IReadOnlyList ?? rows.ToList();
var columns = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (var row in list)
foreach (var key in row.Values.Keys)
columns.Add(key);
return new S8MonitoringRowSet(list, columns);
}
}