DataTable.Select语句报错:无法对String与Decimal执行减法运算
解决DataTable.Select中的类型不匹配减法异常
问题根源
你遇到的System.Data.EvaluateException是因为dataTable中的[double_value]列存储为字符串类型,而在Select表达式中直接和数值类型的newR做减法运算,表达式引擎无法直接对System.String和System.Decimal执行减法操作。
解决方案
方案1:提前转换DataTable列类型(推荐)
先把dataTable里的double_value列从字符串转换为数值类型(比如double),后续表达式运算就不会有类型问题:
// 添加新的数值类型列 dataTable.Columns.Add("double_value_num", typeof(double)); // 遍历行转换值 foreach(DataRow row in dataTable.Rows) { if(!string.IsNullOrEmpty(row["double_value"].ToString())) { row["double_value_num"] = Convert.ToDouble(row["double_value"]); } } // 使用新列执行查询,用Abs()简化绝对值判断 DataRow[] resultRows = dataTable.Select($"column = '{otherSTR}' and (Abs(double_value_num - {newR}) < 0.5)", "Date asc");
注:Abs()的效果和你原代码的(([double_value] - newR)*-1 < 0.5) && (([double_value] - newR)*1 < 0.5)完全一致,都是判断差值的绝对值小于0.5
方案2:在Select表达式中显式转换字符串列
如果不想修改原DataTable结构,可以在表达式中用Convert函数把字符串转成数值:
DataRow[] resultRows = dataTable.Select($"column = '{otherSTR}' and (Abs(Convert.ToDouble([double_value]) - {newR}) < 0.5)", "Date asc");
注意:如果[double_value]存在无法转换为数值的字符串,会触发转换异常,建议提前做数据校验。
方案3:改用LINQ查询(类型更安全)
LINQ在编译期就能做类型检查,避免字符串拼接表达式的类型问题,也更直观:
var resultRows = dataTable.AsEnumerable() .Where(row => row["column"].ToString() == otherSTR && Math.Abs(Convert.ToDouble(row["double_value"]) - newR) < 0.5) .OrderBy(row => row["Date"]) .ToArray();
这种方式不需要拼接字符串表达式,减少语法错误和注入风险(如果otherSTR是用户输入的话)。
额外修正
原代码中dataRow = dataTable.Select(...)存在语法错误:Select返回的是DataRow[]数组,不能直接赋值给单个DataRow变量,需要改为接收数组(比如上面示例中的DataRow[] resultRows)。
内容的提问来源于stack exchange,提问作者Micah Stovall
相关产品推荐
相关产品推荐

