处理DateTime DBNull

时间:2010-10-20 14:16:24

标签: c# datetime dbnull

我在SO上看过很多很多这样的版本,但似乎没有一个版本可以满足我的需求。

我的数据来自供应商数据库,该数据库允许DateTime字段为null。首先,我将数据拉入DataTable。

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

我正在将DataTable转换为List<>用于处理。

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 个答案:

答案 0 :(得分:7)

使用IsDBNull()

System.Convert.IsDBNull(value);

或者如果您有SqlDataReader

reader.IsDBNull(ordinal);

并使DateTime属性可以为空(DateTime?)并在null的情况下设置DBNullField<T>()会自动执行此操作。

答案 1 :(得分:7)

一种可能的选择是使用语法DateTime?

将其存储为可为空的日期时间

以下是关于使用可空类型的link to the MSDN

答案 2 :(得分:2)

这是我用来读取日期时间的一些代码的例子

我确定它可以写得更好,但对我来说运行正常

   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;
    }

答案 3 :(得分:1)

我发现处理此问题的最简单方法是使用“as”关键字将字段强制转换为数据类型。这适用于可以为null的数据库字段,并且非常简单。

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

示例:

    IDataRecord record = FromSomeSqlQuerySource;
    string nullableString;
    DateTime? nullableDateTime;

    nullableString = record["StringFromRecord"] as string;
    nullableDateTime = record["DateTimeFromRecord"] as DateTime?;

答案 4 :(得分:1)

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

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));
    }
}

答案 5 :(得分:0)

您应该使用DataRow["ColumnName"] is DBNull来比较DateTime null。

E.g:

 if(studentDataRow["JoinDate"] is DBNull) { // Do something here }