提问人:Mike Wills 提问时间:10/20/2010 最后编辑:abatishchevMike Wills 更新时间:3/5/2019 访问量:49834
处理 DateTime DBNull
Handling a 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;
}
答:
10赞
abatishchev
10/20/2010
#1
使用 IsDBNull()
System.Convert.IsDBNull(value);
或者,如果您有SqlDataReader
reader.IsDBNull(ordinal);
并使您的属性为 null () 并在 的情况下设置。 将自动执行此操作。DateTime
DateTime?
null
DBNull
Field<T>()
8赞
Scott Chamberlain
10/20/2010
#2
一种可能的选项是将其存储为可为 null 的日期时间,并使用语法DateTime?
下面是有关使用可为 null 类型的 MSDN 的链接
评论
0赞
Mike Wills
10/20/2010
因此,在我的 Equipment 对象上,将字段定义为DateTime
DateTime?
0赞
vc 74
10/20/2010
如果您的设备没有开始或结束日期是有效的商业案例,那么是的。否则,数据库层应引发异常。
1赞
Rob Fonseca-Ensor
10/20/2010
是的 - 这是捷径Nullable<DateTime>
2赞
RoughPlace
10/20/2010
#3
下面是我用来读取 Datetimes 的一些代码示例
我确定它可以写得更好,但对我来说运行良好
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;
}
0赞
Quang Le
11/19/2014
#4
您应该使用 to compare DateTime null。DataRow["ColumnName"] is DBNull
例如:
if(studentDataRow["JoinDate"] is DBNull) { // Do something here }
6赞
Jordan Ryder
11/7/2017
#5
我发现处理此问题的最简单方法是使用“as”关键字将字段转换为您的数据类型。这对于可以为 null 的数据库字段非常有效,并且既漂亮又简单。
以下是有关此的更多详细信息:直接铸造与“作为”操作员?
例:
IDataRecord record = FromSomeSqlQuerySource;
string nullableString;
DateTime? nullableDateTime;
nullableString = record["StringFromRecord"] as string;
nullableDateTime = record["DateTimeFromRecord"] as DateTime?;
0赞
Jonathan Applebaum
3/4/2019
#6
我编写了一个通用的扩展方法,用于我的所有项目:
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));
}
}
评论