调用DataSet的Tables.NewRow()时报空引用错误,求排查解决
问题:创建DataRow时触发「Object reference not set to an instance to an object」错误
问题场景
执行以下代码时触发空引用错误:
dsAddRow = ds.Tables("Nebenkosten").NewRow()
错误提示:
Object reference not set to an instance to an object
已有的声明代码
Public con As New OleDb.OleDbConnection Public dbProvider As String = "PROVIDER=Microsoft.Jet.OLEDB.4.0;" Public myAppDir = System.Environment.GetEnvironmentVariable("USERPROFILE") Public myDatabase As String = myAppDir & "\NebenkostenFuchs.mdb" Public ds As New DataSet Public da As New OleDb.OleDbDataAdapter
按钮保存方法代码
'Open the Database con.ConnectionString = dbProvider & "Data Source = " & myDatabase con.Open() '****************************************************************** Try Dim cb As New OleDb.OleDbCommandBuilder(da) Dim dsAddRow As DataRow dsAddRow = ds.Tables("Nebenkosten").NewRow() ' 触发错误的位置 dsAddRow.Item(1) = cmbObjekt.SelectedItem dsAddRow.Item(2) = cmbJahr.SelectedItem dsAddRow.Item(3) = cmbGruppe.SelectedItem dsAddRow.Item(4) = cmbArt.SelectedItem dsAddRow.Item(5) = cbUmlage.Checked dsAddRow.Item(6) = txtSatz.Text dsAddRow.Item(7) = txtBrutto.Text dsAddRow.Item(8) = txtNetto.Text dsAddRow.Item(9) = txtMwSt.Text ds.Tables("Nebenkosten").Rows.Add(dsAddRow) da.Update(ds, "Nebenkosten") con.Close() Catch ex As Exception MsgBox(ex.Message.ToString, MessageBoxIcon.Error, "Oops - Fehler") con.Close() Exit Sub End Try
数据库中存在名为Nebenkosten的表,ID列为索引(对应Item(0))。
问题原因
DataSet里没有名为"Nebenkosten"的DataTable。你只初始化了ds和da,但从未将数据库中的Nebenkosten表加载到DataSet中,也没有手动创建对应的DataTable结构。调用ds.Tables("Nebenkosten")会返回Nothing,后续调用NewRow()自然触发空引用错误。
解决步骤
1. 先将数据库表加载到DataSet
在使用ds.Tables("Nebenkosten")之前,必须通过DataAdapter从数据库读取表结构(甚至数据)到DataSet。修改按钮方法的代码,在打开连接后添加填充逻辑:
'Open the Database con.ConnectionString = dbProvider & "Data Source = " & myDatabase con.Open() ' 新增:填充DataSet,加载Nebenkosten表结构 da.SelectCommand = New OleDb.OleDbCommand("SELECT * FROM Nebenkosten", con) da.Fill(ds, "Nebenkosten") '****************************************************************** Try Dim cb As New OleDb.OleDbCommandBuilder(da) ' ... 后续代码不变
da.Fill()会自动在DataSet中创建名为"Nebenkosten"的DataTable,并同步数据库中的列结构。
2. 其他优化建议
- 用列名代替索引访问Item:避免后续表结构变化导致索引错位,比如
dsAddRow("Objekt") = cmbObjekt.SelectedItem(替换成实际列名) - 使用Using语句管理连接:确保连接自动释放,避免资源泄漏:
Using con As New OleDb.OleDbConnection(dbProvider & "Data Source = " & myDatabase) con.Open() da.SelectCommand = New OleDb.OleDbCommand("SELECT * FROM Nebenkosten", con) da.Fill(ds, "Nebenkosten") ' ... 后续操作代码 End Using ' 自动关闭并释放连接 - CommandBuilder依赖SelectCommand:只有当DataAdapter的
SelectCommand有效时,CommandBuilder才能生成正确的Insert/Update语句,确保da.SelectCommand已正确赋值。
内容的提问来源于stack exchange,提问作者Andreas Dahl
相关产品推荐
相关产品推荐

