VB.NET读取Access填充ComboBox报转换无效、数组索引越界错误
问题根因
两个异常的触发逻辑非常清晰:
- 指定的转换无效:
OleDbDataReader的GetString()、GetInt32()这类强类型读取方法,要求读取字段的实际存储类型和方法完全匹配。你代码里读的LRN、[Book ID]字段在Access中基本都是数字类型(长整型/整型),并非文本类型,直接调用GetString()读取数字值必然触发转换错误。 - 数组索引超出界限:DataReader的字段索引从0开始计数,你写的两个SQL查询都只返回1个字段,只有索引0是合法访问位置,调用时传索引值1读取肯定越界。
另外你现有代码存在资源泄漏问题:OleDbConnection、OleDbCommand、OleDbDataReader都是非托管资源,用完不释放会持续占用数据库连接,运行次数多了直接报连接池耗尽。而且你代码里第一个connection对象没给出初始化连接串的逻辑,如果两个表在同一个Access库里,完全没必要重复新建第二个连接对象。
修正方案
不要硬套强类型读取方法,直接通过索引器取字段值后调用ToString()转成字符串,不管原字段是数字还是文本类型都能正常读取,不会抛转换错误。所有数据库相关对象全部用Using块包裹,代码执行完会自动释放资源,不用手动写Close()或者Dispose()。
可直接运行的修正代码:
' 两个表同属BookDB.mdb的话直接共用一个连接,不需要重复实例化连接对象 Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=BookDB.mdb") conn.Open() ' 填充第一个GunaComboBox:读取Table1的LRN字段 Dim cmdLrn As New OleDbCommand("SELECT LRN FROM Table1", conn) Using readerLrn As OleDbDataReader = cmdLrn.ExecuteReader() ' 填充前先清原有项,避免重复加载导致下拉项重复 GunaComboBox1.Items.Clear() While readerLrn.Read() ' 过滤NULL值避免报错 If Not readerLrn.IsDBNull(0) Then GunaComboBox1.Items.Add(readerLrn(0).ToString()) End If End While End Using ' 填充第二个GunaComboBox:读取Books1的Book ID字段 Dim cmdBook As New OleDbCommand("SELECT [Book ID] FROM Books1", conn) Using readerBook As OleDbDataReader = cmdBook.ExecuteReader() GunaComboBox2.Items.Clear() While readerBook.Read() ' 单字段查询固定用索引0,不要传1 If Not readerBook.IsDBNull(0) Then GunaComboBox2.Items.Add(readerBook(0).ToString()) End If End While End Using End Using
补充提示
- 如果用的是Access 2007及以上版本的
.accdb格式数据库,把连接串里的Provider改成Microsoft.ACE.OLEDB.12.0,否则会报数据库提供程序找不到的错误。 - 调试时如果拿不准字段索引,可以在拿到reader后查看
FieldCount属性确认返回的字段总数,就不会传错索引值。
内容的提问来源于stack exchange,提问作者Saiko
相关产品推荐
相关产品推荐

