如果我在VB.NET
中有一个DataRow
,并且我想要测试某一列的值是否为Null
,我应该使用哪个方法:
myDataRow.IsNull("Column1")
ORIsDBNull(myDataRow("Column1"))
简短回答: 使用第一种方法,它更快,因为第一种方法使用了预先计算好的结果,而第二种方法需要每次调用时动态重新计算。
详细回答: (你需要阅读 C# 代码来理解这部分;Microsoft 提供了 C# 的框架代码,但 VB 程序员应该能够大致了解正在发生什么)
在 DataRow
的 IsNull
调用中会发生什么:
public bool IsNull(string columnName) {
DataColumn column = GetDataColumn(columnName);
int record = GetDefaultRecord();
return column.IsNull(record);
}
column.IsNull
进行了一个快速的断言,并将调用转发到 DataStorage
,这是一个内部类:
internal bool IsNull(int record) {
Debug.Assert(null != _storage, "no storage");
return _storage.IsNull(record);
}
最后,这里是_storage.IsNull
的作用:
public virtual bool IsNull(int recordNo) {
return this.dbNullBits.Get(recordNo);
}
由于dbNullBits
是一个BitArray
,所以这个操作完成得非常快。
现在考虑索引器myDataRow("Column1")
的作用(在将其结果传递给IsDBNull
之前您调用了此索引器):
get {
DataColumn column = GetDataColumn(columnName);
int record = GetDefaultRecord();
_table.recordManager.VerifyRecord(record, this);
VerifyValueFromStorage(column, DataRowVersion.Default, column[record]);
return column[record];
}
注意到IsNull
方法的前两行和索引器是相同的。然而,接下来的三行需要执行验证并获取值本身。只有在此之后你的代码才能开始计算其目标值——一个指示该值是否为DBNull
的标志。这需要更多的计算,但更重要的是,每次进行检查时都需要进行一些计算。这比使用预先计算的值要慢。
.NET几乎不会无意间给你提供两种做同一件事情的方式。DataRow.IsNull()更加高效,它避免了必须检索列值再检查IsDBNull的过程。在内部,它已经在行创建时确定了列是否为null,因此IsNull()可以非常快速地提供这些信息。因此,它应该是您的首选。
我进行了一些调查,发现了有趣的事实,这些事实提供了更多关于DataRow.IsNull
或IsDBNull
使用的见解。
DataRow.IsNull
- 获取一个值,该值指示指定的DataColumn是否包含空值。
Convert.IsDBNull
- 返回一个指示指定对象是否为DBNull类型的指示。
参考文献:DataRow.IsNull和IsDBNull
最有趣的讨论可以从性能考虑中得出明确的结论。
早期进行了几乎相似的讨论,以下是参考文献:
从数据库设计和使用角度来看,IsNull是正确且被广泛接受的一种方法,用于基于各种数据库技术(包括SQL、DB2、OLAP、MOLAP、RDBMS、MDBMS、SPSS、Essbase等)查询列的值。按照定义,Null表示值的缺失,是未知的,并且Null甚至不等于Null,因此任何与Null相关的附加内容仅仅是为了方便。
我总是使用myDataRow.IsNull("Column1")
,因为在执行SELECT
时,如果值为null
,则返回的是null
而不是DBNull
。
SELECT
语句返回null
?所有其他SQL语句是否返回DBNull
? - CJ7使用 IsDBNull
IsNull 和 IsDBNull 有点不同。一个检查来自所使用的数据库的 DB Null 值,而另一个则只是 Null。