代码之家  ›  专栏  ›  技术社区  ›  Mike Wills

处理日期时间DBNull

  •  8
  • Mike Wills  · 技术社区  · 14 年前

    我已经看过很多很多版本了,但是没有一个能满足我的需要。

    我的数据来自供应商数据库,该数据库允许DateTime字段为空。首先,我将数据拉到数据表中。

    using (SqlCommand cmd = new SqlCommand(sb.ToString(), conn))
    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
    {
        da.Fill(dt);
    }
    

    我正在将数据表转换为列表以进行处理。

    var equipment = from i in dt.AsEnumerable()
        select new Equipment()
        {
            Id = i.Field<string>("ID"),
            BeginDate = i.Field<DateTime>("BeginDate"),
            EndDate = i.Field<DateTime>("EndDate"),
            EstimatedLife = i.Field<double>("EstimatedLife")
        }
    

    那么,在这个实例中如何检查DBNull呢?我试着写一个方法。

        public DateTime CheckDBNull(object dateTime)
        {
            if (dateTime == DBNull.Value)
                return DateTime.MinValue;
            else
                return (DateTime)dateTime;
        }
    
    6 回复  |  直到 14 年前
        1
  •  7
  •   Scott Chamberlain    14 年前

    一个可能的选择是用语法将其存储为可以为空的日期时间 DateTime?

    这是一个 link to the MSDN 关于使用可空类型

        2
  •  9
  •   Michael come lately PhiLho    7 年前

    IsDBNull()

    System.Convert.IsDBNull(value);
    

    或者如果你有 SqlDataReader

    reader.IsDBNull(ordinal);
    

    让你的 DateTime 可为空的属性( DateTime? )并设置 null 万一 DBNull Field<T>() 将自动执行此操作。

        3
  •  2
  •   RoughPlace    14 年前

    我相信可以写得更好,但对我来说还行

       public DateTime? ReadNullableDateTimefromReader(string field, IDataRecord data)
        {
    
            var a = data[field];
            if (a != DBNull.Value)
            {
                return Convert.ToDateTime(a);
            }
            return null;
        }
    
        public DateTime ReadDateTimefromReader(string field, IDataRecord data)
        {
            DateTime value;
            var valueAsString = data[field].ToString();
            try
            {
                value = DateTime.Parse(valueAsString);
            }
            catch (Exception)
            {
                throw new Exception("Cannot read Datetime from reader");
            }
    
            return value;
        }
    
        4
  •  1
  •   Jordan Ryder    7 年前

    我发现处理这个问题最简单的方法是使用“as”关键字将字段转换为数据类型。这对于可以为空的数据库字段非常有用,而且非常简单。

    以下是有关此的详细信息: Direct casting vs 'as' operator?

    例子:

        IDataRecord record = FromSomeSqlQuerySource;
        string nullableString;
        DateTime? nullableDateTime;
    
        nullableString = record["StringFromRecord"] as string;
        nullableDateTime = record["DateTimeFromRecord"] as DateTime?;
    
        5
  •  0
  •   ekostadinov    10 年前

    你应该用 DataRow["ColumnName"] is DBNull

    例如。:

     if(studentDataRow["JoinDate"] is DBNull) { // Do something here }
    
        6
  •  0
  •   Jonathan Applebaum    5 年前

    我写了一个通用的扩展方法,我在所有的项目中都使用它:

    public static object GetValueSafely<T>(this System.Data.DataTable dt, string ColumnName, int index)
    {
        if (typeof(T) == typeof(int))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return 0;
        }
        else if (typeof(T) == typeof(double))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return 0;
        }
        else if (typeof(T) == typeof(decimal))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return 0;
        }
        else if (typeof(T) == typeof(float))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return 0;
        }
        else if (typeof(T) == typeof(string))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return string.Empty;
        }
        else if (typeof(T) == typeof(byte))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return 0;
        }
        else if (typeof(T) == typeof(DateTime))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return DateTime.MinValue;
        }
        else if (typeof(T) == typeof(bool))
        {
            if (dt.Rows[index][ColumnName] != DBNull.Value)
                return dt.Rows[index][ColumnName];
            else
                return false;
        }
        if (dt.Rows[index][ColumnName] != DBNull.Value)
            return dt.Rows[index][ColumnName];
        else
            return null;
    }
    

    private void Example()
    {
        DataTable dt = GetDataFromDb() // get data from database...
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            Console.WriteLine((DateTime)dt.GetValueSafely<DateTime>("SomeDateColumn", i));
            Console.WriteLine((int)dt.GetValueSafely<int>("SomeIntColumn", i));
            Console.WriteLine((string)dt.GetValueSafely<string>("SomeStringColumn", i));
        }
    }
    
    推荐文章