应使用IsDBNull和IsNull中的哪一个



如果在VB.NET中我有DataRow,并且我想测试列值是否为Null,我应该使用:

myDataRow.IsNull("Column1")

IsDBNull(myDataRow("Column1"))

简短回答:使用第一种方法,速度更快,因为第一种方法使用预先计算的结果,而第二种方法每次调用都需要实时重新计算。

长答案:(你需要阅读C#代码才能理解这一部分;MS提供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);
}

由于dbNullBitsBitArray,因此此操作完成得非常快。

现在考虑一下索引器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.IsNullIsDBNull的使用提供了更多的见解。

DataRow.IsNull-获取一个值,该值指示指定的DataColumn是否包含null值。Convert.IsDBNull-返回指定对象是否为DBNull类型的指示。

引用:DataRow.IsNull和IsDBNull

提供明确结论的最有趣的讨论可以从性能考虑中得出

之前进行了几乎类似的讨论,以下是参考文献:

正在数据集数据行中查找null值。。。

检查dbnull的最有效方法。。。

避免检查数据行isdbull。。。

在处理DataRow数据时,最好使用IsDBNull()函数。IsDBNull()的优点是,它检查对象是否表示为null,而不是简单地为null本身,这是一个重要的区别。当您查询数据库中为null的数据行项目时,该项目本身作为对象存在,但它表示null值。如果使用IsNull(),则会丢失NULL值。

从数据库设计和使用的角度来看,基于SQL、DB2、OLAP、MOLAP、RDBMS、MDBMS、SPSS、Essbase等各种数据库技术的使用,IsNull是查询列值的正确且可接受的方式,所以Null的任何附加词都只是一个方便的问题。

我总是使用myDataRow.IsNull("Column1"),因为在发出SELECT时,如果值是null,则返回为null,而不是DBNull

使用IsDBNullIsNull与IsDBNull有点不同。一个是从使用的数据库中检查DB Null值,另一个是Null值。

最新更新