|
|
|
|
|
using System.Data;
|
|
|
|
|
|
using Validation.Core;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Validation.Rule.Data
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 数值范围校验规则
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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}]";
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构造函数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="columnName">列名</param>
|
|
|
|
|
|
/// <param name="minValue">最小值</param>
|
|
|
|
|
|
/// <param name="maxValue">最大值</param>
|
|
|
|
|
|
public RangeValidationRule(string columnName, double minValue, double maxValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.columnName = columnName;
|
|
|
|
|
|
this.minValue = minValue;
|
|
|
|
|
|
this.maxValue = maxValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|