【发布时间】:2018-11-14 15:56:33
【问题描述】:
下面的linq
var subjectMarks = (from DataRow row in objDatatable.Rows
select Convert.ToDecimal(row["EXM_MARKS"])).Sum();
抛出异常,因为某些 row["EXM_MARKS"] 具有非数值,例如 AB 等。
我怎样才能从中得到只有数字的总和?
【问题讨论】:
下面的linq
var subjectMarks = (from DataRow row in objDatatable.Rows
select Convert.ToDecimal(row["EXM_MARKS"])).Sum();
抛出异常,因为某些 row["EXM_MARKS"] 具有非数值,例如 AB 等。
我怎样才能从中得到只有数字的总和?
【问题讨论】:
添加where 子句,过滤掉不能解析为小数的记录。试试:
decimal dummy;
var subjectMarks = (from DataRow row in objDatatable.Rows
where decimal.TryParse(row["EXM_MARKS"], out dummy)
select Convert.ToDecimal(row["EXM_MARKS"])).Sum();
【讨论】:
您可以创建一个扩展方法 SafeConvertToDecimal 并在您的 LINQ 查询中使用它:
var subjectMarks = (from DataRow row in objDatatable.Rows
select row["EXM_MARKS"].SafeConvertToDecimal()).Sum();
此扩展方法如下所示:
public static decimal SafeConvertToDecimal(this object obj)
{
decimal result;
if(!decimal.TryParse(obj.ToString(), out result))
result = 0;
return result;
}
这种方法的优点是它看起来很干净,并且您不会像所有其他答案那样将每个对象转换两次。
【讨论】:
使用
Decimal Z;
var subjectMarks = (from DataRow row in objDatatable.Rows
where Decimal.TryParse (row["EXM_MARKS"], out Z)
select Convert.ToDecimal(row["EXM_MARKS"])).Sum();
【讨论】:
您可以制作一些像这样的扩展实用程序类以获得优雅的解决方案:
public static class TypeExtensions
{
public static bool IsValidDecimal(this string s)
{
decimal result;
return Decimal.TryParse(s, out result);
}
}
并以这种方式使用它:
var subjectMarks = (from DataRow row in objDatatable.Rows
where row["EXM_MARKS"].IsValidDecimal()
select Convert.ToDecimal(row["EXM_MARKS"])).Sum();
希望这会有所帮助。
【讨论】:
对于 linq to sql 查询,您可以使用内置的SqlFunctions.IsNumeric
【讨论】:
var subjectMarks = objDatatable.Rows.Where(row => row["EXM_MARKS"].ToString().All(char.isDigit))
部分解决方案进入:here
【讨论】: