using System.Data; using Validation.Core; namespace Validation.Rule.Data { /// /// 数值范围校验规则 /// public class RangeValidationRule : IValidationRule { private readonly string columnName; private readonly double minValue; private readonly double maxValue; public string RuleName => $"Range_{columnName}"; public string Description => $"检查列'{columnName}'的数值范围[{minValue}, {maxValue}]"; /// /// 构造函数 /// /// 列名 /// 最小值 /// 最大值 public RangeValidationRule(string columnName, double minValue, double maxValue) { this.columnName = columnName; this.minValue = minValue; this.maxValue = maxValue; } /// public ValidationResult Validate(DataTable dataTable) { var result = new ValidationResult { IsValid = true }; if (!dataTable.Columns.Contains(columnName)) { return result; } foreach (DataRow row in dataTable.Rows) { int rowIndex = dataTable.Rows.IndexOf(row); if (!row.IsNull(columnName)) { var value = row[columnName]; if (value is IConvertible convertible) { try { double numericValue = convertible.ToDouble(null); if (numericValue < minValue || numericValue > maxValue) { result.AddError(rowIndex, $"第{rowIndex + 1}行,列'{columnName}'的值{numericValue}超出范围[{minValue}, {maxValue}]"); } } catch { result.AddError(rowIndex, $"第{rowIndex + 1}行,列'{columnName}'的值无法转换为数值"); } } } } return result; } /// public ValidationResult Validate(string[] headers, int rowIndex, object[] values) { var result = new ValidationResult { IsValid = true }; // 查找列索引 int columnIndex = Array.IndexOf(headers, columnName); // 如果找不到列或值为空,则直接返回 if (columnIndex < 0 || columnIndex >= values.Length || values[columnIndex] == null || values[columnIndex] == DBNull.Value) { return result; } var value = values[columnIndex]; if (value is IConvertible convertible) { try { double numericValue = convertible.ToDouble(null); if (numericValue < minValue || numericValue > maxValue) { result.AddError(rowIndex, $"第{rowIndex + 1}行,列'{columnName}'的值{numericValue}超出范围[{minValue}, {maxValue}]"); } } catch { result.AddError(rowIndex, $"第{rowIndex + 1}行,列'{columnName}'的值无法转换为数值"); } } return result; } } }