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


陷阱22
空穴来风
——当ExecuteScalar返回值为空时的陷阱

1.陷阱产生的场景

ExecuteScalar方法是ADO.NET的Command对象的一个重要方法,该方法实现执行查询并返回查询结果集中第一行第一列的值,返回值类型为object。当结果集中的第一行第一列为空时,该方法返回值为DBNull.Value。

例4.22 当ExecuteScalar返回值为空时的陷阱(光盘位置:光盘\MR\Instance\4\22\UseExecuteScalar),该实例的实现过程如下。

本实例实现统计某种商品的销售总量,并在控制台命令行中输出销售总量,本实例的Main方法实现获取商品的销售总量,并在控制台中输出,其代码如下:

在上面的代码中,用到了自定义方法GetSaleQuantity,该方法通过传入一条查询SQL语句来获取某种商品的销售总量,其代码如下:

在上面的代码中,ExecuteScalar方法返回某种商品的销售总量,若该商品还未发生销售,则该方法的返回值为DBNull.Value。若判断ExecuteScalar方法返回值为空,则自定义方法GetSaleQuantity返回值为0,否则返回实际某种商品的销售总量。编译后运行该程序,却出现如图4.43所示的异常提示。

图4.43 异常提示

提示

DBNull.Value是DBNull类型的唯一实例,它的类型也为DBNull。

2.陷阱的分析

异常信息提示“可为空的对象必须具有一个值”,此处可为空的对象是指变量int Quantity,它是一个可空类型的变量。那么异常信息隐含的意思是变量intQuantity没有值,即值为空。但是我们知道,变量intQuantity的值是由ExecuteScalar方法的返回值转换而来的,若变量intQuantity的值为空,则ExecuteScalar方法的返回值必为DBNull.Value。由于这二者之间存在类型转换的关系,反向可以推断出intQuantity的值也为DBNull.Value,这样程序应该执行if语句块内的代码,而实际程序执行了else语句块内的代码。那么实际的情况是否真的像分析的这样吗?接下来添加对ExecuteScalar方法的快速监视,如图4.44所示。

从图4.44中可以看出,该方法的返回值类型为DBNull,即返回值为DBNull.Value,而变量intQuantity的值是由该方法的返回值转换而来的,那么变量intQuantity的值是否也为DBNull.Value呢?接下来添加对变量intQuantity的快速监视,如图4.45所示。

图4.44 快速监视

图4.45 快速监视

从图4.45中可以看出,变量intQuantity的值确实为null,而非DBNull.Value。这说明使用as运算符将DBNull.Value转换为可空类型时,其结果为null,而非DBNull.Value,这就是问题所在。

3.陷阱的解决方法

根据上面的分析,本实例采取两种方法来修改程序。

❏ 使用Nullable<int>类型的HasValue属性判断变量intQuantity是否有值,其代码如下:

❏ 使用null来做空值判断,代码如下: 1HOZkhQVKp5Iw40SpVfw5ETcYrjSd17hfowlBCm7F8Ku/wzVz3JiOx6B9Qgk8Fo9

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