Vb.net 使数据表DBNull的Select和ToArray为aware
从DataTable中提取数据时引发异常“无法将对象从DBNull转换为其他类型”。显然,下面的语法不是“DBNull-aware”。如果在强制转换过程中发现DBNull,是否有方法防止引发此异常Vb.net 使数据表DBNull的Select和ToArray为aware,vb.net,exception,select,datatable,toarray,Vb.net,Exception,Select,Datatable,Toarray,从DataTable中提取数据时引发异常“无法将对象从DBNull转换为其他类型”。显然,下面的语法不是“DBNull-aware”。如果在强制转换过程中发现DBNull,是否有方法防止引发此异常 Dim arrayOfDoubles()() As Double = DT.AsEnumerable().Select(Function(x) {Convert.ToDouble(x("Age")), Convert.ToDouble(x("Weight"))
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()
不必在每一个子句(where和select)中都特别说明,您可以使用一些集中的“技巧”来简化代码,如下所示:
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
如果我知道你需要这样的东西在哪里 在
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()
不必在每一个子句(where和select)中都特别说明,您可以使用一些集中的“技巧”来简化代码,如下所示:
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
你希望会发生什么呢?接受的答案将忽略这些记录,但还有其他选项,例如转换为零。始终提供完整和清晰的解释。@jmcilhinney您在上下文中是正确的(我认为是一样的),但有时人们必须知道,SO的用户并不是全职致力于此网站以给出清晰和完整的答案(因为MS guide也存在这种情况)然后,他们会根据自己需要花多少时间做出明确而全面的回应(不幸的是)。保持安全。@G3nt\u M3caj,我并没有批评你的回答。我批评这个问题没有提供足够的信息,没有做出假设就可以给出答案。答案是有效的。我从未将null设置为零,因为这就像在没有测量值的情况下说什么都不等于零一样。告诉学生一件危险的事,因为缺失到零会导致特征值频率直方图中零处出现峰值,称为间歇性(湍流)。用平均值、中位数、最小值、最大值替换空值的热板插补是可选的,但您不知道空值是完全随机缺失、随机缺失还是非随机缺失,所以插补可能会有偏差。您预计会发生什么情况?接受的答案将忽略这些记录,但还有其他选项,例如转换为零。始终提供完整和清晰的解释。@jmcilhinney您在上下文中是正确的(我认为是一样的),但有时人们必须知道,SO的用户并不是全职致力于此网站以给出清晰和完整的答案(因为MS guide也存在这种情况)然后,他们会根据自己需要花多少时间做出明确而全面的回应(不幸的是)。保持安全。@G3nt\u M3caj,我并没有批评你的回答。我批评这个问题没有提供足够的信息,没有做出假设就可以给出答案。答案是有效的。我从未将null设置为零,因为这就像在没有测量值的情况下说什么都不等于零一样。告诉学生一件危险的事,因为缺失到零会导致特征值频率直方图中零处出现峰值,称为间歇性(湍流)。用均值、中位数、最小值、最大值替换空值是可选的,但你不知道空值是完全随机缺失、随机缺失还是非随机缺失,所以插补可能会有偏差。这就像一种魅力,是的,有许多实例需要在没有任何空值的情况下获取多特征实值矩阵(请参见修改后的OP)-我实际上是从一个列名称的字符串数组开始的,我知道它是双精度的。那么,有没有一种方法可以将所有请求的列名连接到一个查询字符串中,然后将其注入Select命令中呢?是的,您可以做一些技巧(例如:使用Func(Of List(Of string))来这里我没有在这台机器上安装VS,但我会展示一些东西tomorrow@wrstks,已更新,忽略填充DataTableIt worked的部分,但在检查数组中的行值时,每行都列为“内存查询”所以我看不到数字。有没有办法消除这种情况,并将内存查询转换为双倍查询?(也许这就是您上次的循环所做的,但是,我正在尝试避免在ToArray调用后循环)。这就像一个符咒,是的,有很多实例需要获取没有任何空值的多特征实值矩阵。(请参阅修改后的OP)-我实际上是从一个字符串数组开始的,我知道它是双精度的。那么有没有办法将所有请求的列名连接在一个查询字符串中,然后将其注入Select命令中?是的,您可以做一些技巧(例如:使用Func(of List(of string))呢这里我没有在这台机器上安装VS,但我会展示一些东西tomorrow@wrstks,已更新,忽略填充DataTableIt worked的部分,但在检查数组中的行值时,每行都列为“内存查询”所以我看不到数字。有没有办法消除这种情况,并将内存查询转换为双倍查询?(也许这就是您上次的循环所做的,但是,我正在尝试避免在ToArray调用后循环)。