我有一个下面的DataTable,它可以有任意数量的行,每行中的列大约是40。 我正在尝试验证每个列,如果它无法在新表中复制该行。
private void ValidateRows(DataTable csvDataTable)
{
DataTable invalidatedTable = new DataTable();
invalidatedTable = csvDataTable.Clone();
// Loop over all the rows in the datatable
foreach (DataRow row in csvDataTable.Rows)
{
bool invalidated = false;
if (row["ID"].ToString() == "")
{
invalidated = true;
row["ID"] = "not valid";
}
if (row["Name"].ToString() != "test")
{
invalidated = true;
}
//and rest of the validation
//if invalid
if (invalidated)
{
invalidatedTable.Rows.Add(row.ItemArray);
}
} // End Loop
}
如果有一种有效的方法可以进行验证吗? 我们可以申请哪种模式来验证看起来更干净的行吗?
由于
答案 0 :(得分:0)
您可以在不使用布尔变量的情况下自动添加无效记录:
foreach (DataRow row in csvDataTable.Rows)
{
if (row["ID"].ToString() == "" || row["Name"].ToString() != "test")
{
invalidatedTable.Rows.Add(row.ItemArray);
if (row["ID"].ToString() == "")
row["ID"] = "not valid";
}
}
这看起来更干净,更易读。
答案 1 :(得分:0)
您正在检查每一列,即使某些早期列已使该行无效。如果您期望大量无效行,那么这将显着影响您的表现。
如果检查没有副作用(如Name
检查),请随意跳过。
if (!invalidated && row["Name"].ToString() != "test")
{
invalidated = true;
}
如果没有关于行无效的更多细节,我不确定你能做的还有更多。
答案 2 :(得分:0)
如果您的大多数验证条件都很简单(并且没有副作用),您可以将每个条件存储为委托,然后循环遍历它们。
private void ValidateRows(DataTable csvDataTable)
{
DataTable invalidatedTable = new DataTable();
invalidatedTable = csvDataTable.Clone();
List<Func<DataRow, bool>> validators = new List<Func<DataRow, bool>>
{
row => row["ID"].ToString() == "",
row => row["Name"].ToString() != "test",
};
// Loop over all the rows in the datatable
foreach (DataRow row in csvDataTable.Rows)
{
bool valid = validators.All(validator => validator(row));
if (!valid)
{
invalidatedTable.Rows.Add(row.ItemArray);
}
} // End Loop
}
每个验证方法都成为validators
列表中的一个附加条目。
(请注意,对validators.All
的调用是短路的 - 只要其中一个验证失败,就不会为该特定行运行其他任何验证。)
这种方法的缺点是,为特定验证执行副作用(例如在原始代码中设置row["ID"] = "not valid"
)会变得很麻烦。您要么需要增强委托,而不仅仅是单行,如下所示:
List<Func<DataRow, bool>> validators = new List<Func<DataRow, bool>>
{
row =>
{
bool idIsEmpty = row["ID"].ToString() == "";
if (idIsEmpty) row["ID"] = "not valid";
return !idIsEmpty;
},
row => row["Name"].ToString() != "test",
};
或将这些案例分解为单独的函数:
List<Func<DataRow, bool>> validators = new List<Func<DataRow, bool>>
{
RowIdValidation,
row => row["Name"].ToString() != "test",
};
... snip ...
private static bool RowIdValidation(DataRow row)
{
bool idIsEmpty = row["ID"].ToString() == "";
if (idIsEmpty) row["ID"] = "not valid";
return !idIsEmpty;
}
此外(如@MotKohn所述),您需要修改代码以防止All
的短路行为导致跳过副作用,可能是通过使用普通的foreach
循环代替。
TL; DR - 如果您在验证后发生副作用,切换到此样式可能会使您的代码 lot 更难以遵循。