购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP


陷阱25
埋下祸患
——在DataGridView中绑定自增列产生的陷阱

1.陷阱产生的场景

数据表中的自增列由数据库管理系统内部自动管理,不需要也不允许外部程序干预。由于自增列值的唯一性,所以常用来唯一标识数据记录,这样可以通过自增列的值来修改或删除某一条指定的记录。但若将自增列绑定到DataGridView控件中,可能会发生异常。

例4.25 在DataGridView中绑定自增列产生的陷阱(光盘位置:光盘\MR\Instance\ 4\25\BindingAutoId),该实例的实现过程如下。

在本实例的窗体中添加一个DataGridView控件、一个BindingSource组件及其他相关控件,并在DataGridView控件的Columns属性中绑定了一个自增列Id。窗口运行效果如图4.52所示。

图4.52 绑定自增列的窗体

在该窗体的Load事件中,BindingSource组件绑定到数据源,并将DataGridView控件绑定到BindingSource组件来显示数据,代码如下:

单击工具栏中的“保存”按钮,程序先在DataGridView控件添加一个行,然后设置该行各个单元格的值,最后使用业务逻辑类Goods的Commit方法提交数据库。“保存”按钮的Click事件的主要代码如下:

说明

虽然在DataGridView控件中绑定了自增Id列,但在上面代码中并没有给Id列的对应单元格赋值,因为Id列的值由数据库管理系统内部自动管理,不允许外界的干预。

上面的代码用到了Goods类的Commit方法,该方法实现提交在DataGridView控件中对数据的更改,包括修改记录、插入记录、删除记录,该方法的代码如下:

单击工具栏中的“删除”按钮,程序首先获取DataGridView控件中的当前行,然后通过该控件的Rows属性的Remove方法删除当前行,“删除”按钮的Click事件的主要代码如下:

说明

当删除DataGridView控件中的某行时,在数据库内部实际是通过自增列Id的值来唯一确定被删除的记录。

运行本实例,首先在DataGridView控件中添加一条记录,注意不要马上退出窗体,然后紧接着删除新添加的那条记录,这时程序会出现如图4.53所示的异常提示。

图4.53 异常提示

说明

在DataGridView控件中添加一条记录之后退出窗体,然后再次运行程序,这时再删除最近添加的那条记录,程序完全可以正常删除。

2.陷阱的分析

异常信息中提示“DeleteCommand影响了预期1条记录中的0条”。对异常信息进行初步分析的结果就是,虽然C#程序向数据库中提交了删除指定一条记录的命令,但该命令并没有删除预期的那条记录。接下来分析数据库执行删除记录操作,数据库要删除指定的一条记录,通常需要使用主键来确定被删除的记录,本实例数据表的主键为自增列Id。于是接下来添加对当前行的引用dgvr的快速监视,查看到当前行的自增列Id的值如图4.54所示。

图4.54 快速监视

从图4.54中可以看出,当前行自增列Id的值为空。那么让数据库删除一个自增列Id的值等于空的数据记录,当然是要失败的,所以问题找到了。那么为什么新增行的Id列的值为空呢?其实问题很简单,就是上面曾经提到过的,自增列Id的值由数据库管理系统自动管理,不允许外界干预。当C#程序在DataGridView控件中添加行并提交数据库成功后,在不重新运行窗体的情况下,数据库中新增行的Id列的值不会自动绑定到DataGridView控件上,这样DataGridView控件中当前行的Id列的值自然为空。

3.陷阱的解决方法

根据上面的分析得知,解决办法就是在添加新行成功后,重新绑定DataGridView控件到数据源。在“保存”按钮的Click事件代码中,修改部分的代码如下: mWw/ynCD/3G5eLfakb/eck6jsWGdQQnXAVa5d39/HUTA14TjZGLlVtILGVj7ry7B

点击中间区域
呼出菜单
上一章
目录
下一章
×