使数据表DBNull的Select和ToArray可感知



异常"对象不能从DBNull强制转换为其他类型";从DataTable中提取数据时引发。显然,下面的语法不是";DBNull感知"如果在强制转换过程中发现DBNull,是否有方法防止引发此异常?

Dim arrayOfDoubles()() As Double = DT.AsEnumerable().Select(Function(x) {Convert.ToDouble(x("Age")), Convert.ToDouble(x("Weight")), Convert.ToDouble(x("Location"))}).ToArray()

此外,我实际上是从一个字符串数组开始的,这些列的名称是双的。那么,有没有一种方法可以将所有请求的列名连接在一个查询字符串中,然后将其注入Select语句中?按照这种方式,我将只为所有列都不是DBNull的行获得一个双数组。

如果我很清楚你需要这样的东西在Where子句中,如果有DbNull值,则可以测试字段。

Dim arrayOfDoubles()() As Double = DT.AsEnumerable().
Where(Function(f) f("Age") IsNot DBNull.Value AndAlso f("Weight") IsNot DBNull.Value).
Select(Function(x) {Convert.ToDouble(x("Age")), Convert.ToDouble(x("Weight")), Convert.ToDouble(x("Location"))}).ToArray()

不需要在每个子句中都具体说明(在哪里和选择中(,您可以使用一些集中的"技巧"来简化您的代码,如下所示:

Dim DT As DataTable = New DataTable
DT.Columns.Add("Age", GetType(Double))
DT.Columns.Add("Weight", GetType(Double))
DT.Columns.Add("Location", GetType(Double))
DT.Columns.Add("Moves", GetType(Double))
For i As Integer = 0 To 10
Dim dr As DataRow = DT.NewRow
If i Mod 2 = 0 Then
dr.ItemArray = {i, DBNull.Value, i + 2, DBNull.Value}
Else
dr.ItemArray = {i, i + 1, i + 2, i + 3}
End If
DT.Rows.Add(dr)
Next

'============================================================================
Dim flds As List(Of String) = {"Age", "Weight", "Location", "Moves"}.ToList
Dim arrayOfDoubles()() As Double = DT.AsEnumerable().
Where(Function(f) flds.Where(Function(el) f(el) IsNot DBNull.Value).Count = flds.Count).
Select(Function(x) flds.Select(Function(el) Convert.ToDouble(x(el))).ToArray).ToArray
'====================================================================================
For Each el In arrayOfDoubles
Debug.Print("Age:      " & el(flds.IndexOf("Age")).ToString)
Debug.Print("Weight:   " & el(flds.IndexOf("Weight")).ToString)
Debug.Print("Location: " & el(flds.IndexOf("Location")).ToString)
Debug.Print("Location: " & el(flds.IndexOf("Moves")).ToString)
Next

最新更新