【问题标题】:Finding null value in Dataset - DataRow.IsNull method vs ==DbNull.Value - c#在数据集中查找空值 - DataRow.IsNull 方法 vs ==DbNull.Value - c#
【发布时间】:2011-08-01 17:54:57
【问题描述】:

与检查行是否等于 DbNull.value 相比,使用 c# 方法 DataRow.IsNull 确定空值有什么好处?

if(ds.Tables[0].Rows[0].IsNull("ROWNAME")) {do stuff}

if(ds.Tables[0].Rows[0]["ROWNAME"] == DbNull.value) {do stuff}

【问题讨论】:

    标签: c#-4.0 dataset datarow dbnull isnull


    【解决方案1】:

    DBNull.Value != null

    DBNull.Value 代表具有值<NULL> 的列。 弹出一个表并返回一些行,查看任何行中的任何列是否包含<NULL>(ctrl 0) 值。如果你看到一个等同于 DBNull.Value。

    如果您将值设置为 null 或 DBNull.Value,那么您将需要使用 IsNull()。 如果值设置为 null 或 DBNull.Value,则返回 true。

    考虑以下几点:

    row["myCol"] = null;

    row["myCol"] = DBNull.Value

    if (row["myCol"] == DBNull.Value) //返回真

    if (row["myCol"] == null) //返回假

    if (row.IsNull("myCol")) //返回真

    关键是如果您只是检查 null 或 DBNull.Value 使用 IsNull,如果您只检查 DBNull.Value 明确说明并使用它。

    【讨论】:

    • 这有点误导。当您设置 row["myCol"] = null 时,它实际上将其设置为 DBNull.Value。 row.IsNull("myCol") 和 row("myCol") == DBNull.Value 实际上是等价的。
    • 谢谢@JonH。很好的解释
    • 行["myCol"] = null; if (row["myCol"] == null) //返回假
    • 我并不是说 DBNull.Value == null。我是说在 DataRow 类内部,当您设置它的值时,它会将 null 转换为 DBNull.Value。
    • @Seth 在这里是正确的。 DataRow 上的 this[DataColumn] 的设置器不允许将真正的空引用分配给底层存储阵列。如果列的数据类型是值类型,那么它会抛出异常。否则,它将分配DBNull.ValueINullable 仅在使用 SqlDataTypes 之一时使用,不适用于普通类型。
    【解决方案2】:

    一方面,它减少了打字。除此之外,我认为它们是等价的。

    试图澄清我为什么说它们是等价的。

    [Test()]
    public void test() {
        var t = new System.Data.DataTable();
        t.Columns.Add("col1");
        var r = t.NewRow();
    
            // null is converted to DBNull.Value by DataRow
            r["col1"] = null;
            Assert.IsFalse(r["col1"] == null);
            Assert.IsTrue(r["col1"] == DBNull.Value);
            Assert.IsTrue(r.IsNull("col1"));
    
            // nullable types w/o values are also converted
            int? val = null;
            Assert.IsFalse(val.HasValue);
            r["col1"] = val;
            Assert.IsTrue(r["col1"] == DBNull.Value);
            Assert.IsTrue(r.IsNull("col1"));
    
    
    }
    

    【讨论】:

    • 其实不仅仅是打字。如果我将一列设置为 null 并检查它是否等于 DBNull.Value 然后它返回 false。如果我要使用 IsNull() 方法,那么无论我是在检查 null 还是 DBNull.Value,结果都会返回 true。在某些情况下,您可能想要这样。
    • 对,但你没有提到,你说只是打字少了。如果值为 nullDBNull.Value,则 IsNull 返回 true。两者不相等。
    • @JonH - 这是因为当您将数据行中的值设置为 null 时,它实际上将其设置为 DBNull.Value。
    • @Seth Reno - 不不不DBNull.Value != null
    • 它们在功能上是等效的,但IsNull 更快,因为它检查底层存储层的空位以查找该记录,而不是实际检索值。
    【解决方案3】:

    FWIW,我写了一堆 DataRow 扩展方法 — CastAsXXX() — 以避免不得不处理 DB 可空性...或者至少推迟一点 B^)。这是我的CastAsInt()CastAsIntNullable() 方法:

    #region downcast to int
    
    public static int CastAsInt( this DataRow row , int index )
    {
      return toInt( row[index] ) ;
    }
    public static int CastAsInt( this DataRow row , string columnName )
    {
      return toInt( row[columnName] ) ;
    }
    
    public static int? CastAsIntNullable( this DataRow row , int index )
    {
      return toIntNullable( row[index] );
    }
    public static int? CastAsIntNullable( this DataRow row , string columnName )
    {
      return toIntNullable( row[columnName] ) ;
    }
    
    #region conversion helpers
    
    private static int toInt( object o )
    {
      int value = (int)o;
      return value;
    }
    
    private static int? toIntNullable( object o )
    {
      bool hasValue = !( o is DBNull );
      int? value    = ( hasValue ? (int?) o : (int?) null ) ;
      return value;
    }
    
    #endregion conversion helpers
    
    #endregion downcast to int
    

    使用非常简单。您只需提前说明您的期望即可。

    DataRow dr = GetADataRowFromSomewhere() ;
    // Throws NullReferenceException if the column is null
    int     x  = dr.CastAsInt(         "column_1" ) ;
    // Is perfectly happy with nulls (as it should be)
    int?    y  = dr.CastAsIntNullable( "column_1" ) ;
    

    我尝试将它们设为通用,但没有骰子,除非我愿意将数据库中的 NULL 与类型的默认值(例如,数字类型为 0)相关联,但我不是。

    【讨论】:

    【解决方案4】:

    没有真正的实用好处。使用对您来说更具可读性的任何一个。

    至于它们之间的特殊差异,基本答案是IsNull 查询列中特定记录的空状态。使用== DBNull.Value 实际上检索该值并在它实际上为空的情况下进行替换。换句话说,IsNull 在不实际检索值的情况下检查状态,因此速度稍快(至少理论上如此)。

    如果您要使用自定义存储类型,从理论上讲,对于空值,列可能会返回 DBNull.Value 以外的 other 值,但这永远不会完成(根据我的经验)。如果是这种情况,IsNull 将处理存储类型使用 DBNull.Value 以外的其他内容的情况,但是,同样,我从未见过这样做过。

    【讨论】:

      【解决方案5】:

      它让表在行中有检查空值

      if (! DBNull.Value.Equals(dataset.Tables["tablename"].Rows[n][0].ToString())) {
          //enter code here
      } else {
        //enter code here
      }
      

      【讨论】:

      • 什么?你想说什么?这根本不涉及被问到的差异,所以它似乎没有回答这个问题!?我也不明白你想对 ToString 的调用做什么。这和这里有什么关系?
      猜你喜欢
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 2018-02-10
      • 2015-03-13
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      相关资源
      最近更新 更多