从DataTable查询整数ID列表时遇DBNull转换异常的解决方法
问题:查询DataTable整数ID列表生成DataView筛选条件时遭遇DBNull转换异常
尝试从DataTable中查询符合特定条件的整数ID列表,拼接为字符串后用作DataView的筛选条件,代码如下:
Dim dvFilteredList As New DataView(dtbList) Dim existingSelections = (From dtr In dtbMain.AsEnumerable Where dtr.Field(Of String)("Field1") = strField1Value _ And dtr.Field(Of String)("Field2") = strField2Value _ And dtr.Field(Of String)("Field3") = strField3Value _ And Not IsDBNull(dtr.Field(Of Integer)("SomeID")) Select New With {.SomeID = dtr.Field(Of Integer)("SomeID")}).ToList Dim strViewFilter As String = "[SomeID] NOT IN (" & String.Join(",", existingSelections) & ")" dvFilteredList.RowFilter = strViewFilter
执行时抛出异常:
Cannot cast DBNull.Value to type 'System.Int32'. Please use a nullable type.
解决方案
异常原因
代码中Not IsDBNull(dtr.Field(Of Integer)("SomeID"))的判断逻辑存在问题:调用Field(Of Integer)时会先尝试将DBNull转换为非可空的Int32,这一步直接触发了转换异常,导致后续的过滤判断无法执行。
修正步骤
- 用可空整数类型处理DBNull:将
Field(Of Integer)改为Field(Of Integer?),DBNull会被安全转换为Nothing,再通过HasValue判断是否为有效整数。 - 直接选择ID值而非匿名类型:避免
String.Join时生成{ SomeID = 1 }这类无效格式,直接提取整数ID。 - 处理空列表场景:如果没有符合条件的ID,避免生成
NOT IN ()这种语法错误的筛选条件。
修正后完整代码
Dim dvFilteredList As New DataView(dtbList) ' 使用可空Integer类型过滤DBNull行,直接选择ID值 Dim existingSelections = (From dtr In dtbMain.AsEnumerable Where dtr.Field(Of String)("Field1") = strField1Value _ And dtr.Field(Of String)("Field2") = strField2Value _ And dtr.Field(Of String)("Field3") = strField3Value _ And dtr.Field(Of Integer?)("SomeID").HasValue Select dtr.Field(Of Integer?)("SomeID").Value).ToList ' 空列表时不设置筛选条件,避免语法错误 Dim strViewFilter As String = If(existingSelections.Any(), "[SomeID] NOT IN (" & String.Join(",", existingSelections) & ")", "") dvFilteredList.RowFilter = strViewFilter
关键说明
Integer?(可空Int32)是.NET专门用来处理值类型可能为null的场景,调用Field(Of Integer?)时,DBNull会被转换为Nothing,不会抛出转换异常。- 直接选择
.Value获取有效整数,String.Join会生成1,2,3这类符合DataView筛选语法的字符串。 - 空列表判断确保筛选条件始终合法,避免因无匹配ID导致的语法错误。
内容的提问来源于stack exchange,提问作者Alan O'Brien
相关产品推荐
相关产品推荐

