我使用SQLdatareader从数据库构建poco。除非在数据库中遇到空值,否则代码可以正常工作。例如,如果数据库中的FirstName列包含空值,则抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
在这种情况下处理空值的最佳方法是什么?
我使用SQLdatareader从数据库构建poco。除非在数据库中遇到空值,否则代码可以正常工作。例如,如果数据库中的FirstName列包含空值,则抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
在这种情况下处理空值的最佳方法是什么?
当前回答
Convert明智地处理DbNull。
employee.FirstName = Convert.ToString(sqlreader.GetValue(indexFirstName));
其他回答
这个方法依赖于indexFirstName,它应该是一个从零开始的列序数。
if(!sqlReader.IsDBNull(indexFirstName))
{
employee.FirstName = sqlreader.GetString(indexFirstName);
}
如果你不知道列的索引,但不想检查一个名称,你可以使用这个扩展方法:
public static class DataRecordExtensions
{
public static bool HasColumn(this IDataRecord dr, string columnName)
{
for (int i=0; i < dr.FieldCount; i++)
{
if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
}
然后像这样使用方法:
if(sqlReader.HasColumn("FirstName"))
{
employee.FirstName = sqlreader["FirstName"];
}
我想你会想用:
SqlReader.IsDBNull(indexFirstName)
下面是其他人可以根据@marc_s的答案使用的helper类:
public static class SQLDataReaderExtensions
{
public static int SafeGetInt(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? 0 : dataReader.GetInt32(fieldIndex);
}
public static int? SafeGetNullableInt(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.GetValue(fieldIndex) as int?;
}
public static string SafeGetString(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? string.Empty : dataReader.GetString(fieldIndex);
}
public static DateTime? SafeGetNullableDateTime(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.GetValue(fieldIndex) as DateTime?;
}
public static bool SafeGetBoolean(this SqlDataReader dataReader, string fieldName)
{
return SafeGetBoolean(dataReader, fieldName, false);
}
public static bool SafeGetBoolean(this SqlDataReader dataReader, string fieldName, bool defaultValue)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? defaultValue : dataReader.GetBoolean(fieldIndex);
}
}
如何创建帮助方法
为字符串
private static string MyStringConverter(object o)
{
if (o == DBNull.Value || o == null)
return "";
return o.ToString();
}
使用
MyStringConverter(read["indexStringValue"])
为整数
private static int MyIntonverter(object o)
{
if (o == DBNull.Value || o == null)
return 0;
return Convert.ToInt32(o);
}
使用
MyIntonverter(read["indexIntValue"])
为日期
private static DateTime? MyDateConverter(object o)
{
return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
}
使用
MyDateConverter(read["indexDateValue"])
注意:对于DateTime声明变量为
DateTime? variable;
您可以编写一个通用函数来检查Null,并在它为Null时包含默认值。读取Datareader时调用此函数
public T CheckNull<T>(object obj)
{
return (obj == DBNull.Value ? default(T) : (T)obj);
}
读取Datareader时使用
while (dr.Read())
{
tblBPN_InTrRecon Bpn = new tblBPN_InTrRecon();
Bpn.BPN_Date = CheckNull<DateTime?>(dr["BPN_Date"]);
Bpn.Cust_Backorder_Qty = CheckNull<int?>(dr["Cust_Backorder_Qty"]);
Bpn.Cust_Min = CheckNull<int?>(dr["Cust_Min"]);
}