VB.NET中DataTable.Select()查询数据异常问题及解决
DataTable数据查找的异常问题与解决
问题场景
从ODBC获取的DataTable(dt)中匹配特定值,LookupCode从DataGridView获取的值确认正确,但使用DataTable.Select()方法获取匹配行时遇到以下问题:
- 初始代码触发
System.NullReferenceException,但确认dt中存在目标数据 - 修改Select语句后,又出现“无法在System.Int32和System.String类型上执行'='操作”的错误
初始代码
Imports System.Linq ... Dim dt As New DataTable Dim LookupRow As DataRow Dim LookupCode As String If dt.Rows.Count > 0 Then For Each row As DataGridViewRow In MagDataGridView.Rows LookupCode = row.Cells(1).Value LookupRow = dt.Select("'" & dt.Columns(0).ColumnName & "'='" & LookupCode & "'") .FirstOrDefault row.Cells(5).Value = LookupRow.Item(1) Next End If
第一次修改后的代码(触发类型不匹配错误)
LookupRow = dt.Select(dt.Columns(0).ColumnName & "='" & LookupCode & "'") .First
错误原因分析
初始代码的NullReferenceException:
代码中给列名套了单引号,导致Select语句把列名当成了字符串常量而非列名,根本查不到匹配行,FirstOrDefault返回Nothing,后续访问LookupRow.Item(1)自然触发空引用异常。类型不匹配错误:
去掉列名的单引号后,Select语句能正确识别列,但该列的实际数据类型是Int32,而LookupCode是String类型,DataTable.Select()的表达式不支持自动类型转换,直接用=比较就会触发类型不兼容的错误。
正确解决方法:使用LINQ to DataSet
通过LINQ实现类型安全的查询,避免Select语句的字符串表达式陷阱:
Dim fRow = From row In dt.AsEnumerable() Where row.Field(Of String)(dt.Columns(0).ColumnName) = LookupCode LookupRow = fRow.First row.Cells(5).Value = LookupRow.Item(1)
注:如果列的实际类型是Int32,可以把Field(Of String)改为Field(Of Integer),同时将LookupCode转为整数类型后再比较,避免类型不匹配问题。
内容的提问来源于stack exchange,提问作者Mateusz
相关产品推荐
相关产品推荐

