我使用SQLdatareader从数据库构建poco。除非在数据库中遇到空值,否则代码可以正常工作。例如,如果数据库中的FirstName列包含空值,则抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
在这种情况下处理空值的最佳方法是什么?
我使用SQLdatareader从数据库构建poco。除非在数据库中遇到空值,否则代码可以正常工作。例如,如果数据库中的FirstName列包含空值,则抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
在这种情况下处理空值的最佳方法是什么?
当前回答
我倾向于用合适的东西替换SELECT语句中的空值。
SELECT ISNULL(firstname, '') FROM people
在这里,我将每个null替换为一个空白字符串。在这种情况下,代码不会抛出错误。
其他回答
我倾向于用合适的东西替换SELECT语句中的空值。
SELECT ISNULL(firstname, '') FROM people
在这里,我将每个null替换为一个空白字符串。在这种情况下,代码不会抛出错误。
下面是其他人可以根据@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);
}
}
IsDbNull(int)通常比使用GetSqlDateTime等方法然后与DBNull.Value进行比较要慢得多。试试SqlDataReader的这些扩展方法。
public static T Def<T>(this SqlDataReader r, int ord)
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return default(T);
return ((INullable)t).IsNull ? default(T) : (T)t;
}
public static T? Val<T>(this SqlDataReader r, int ord) where T:struct
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return null;
return ((INullable)t).IsNull ? (T?)null : (T)t;
}
public static T Ref<T>(this SqlDataReader r, int ord) where T : class
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return null;
return ((INullable)t).IsNull ? null : (T)t;
}
像这样使用它们:
var dd = r.Val<DateTime>(ords[4]);
var ii = r.Def<int>(ords[0]);
int nn = r.Def<int>(ords[0]);
当在数据读取器中使用列名返回行时,我不认为有NULL列值。
如果你做datareader["columnName"].ToString();它总是会给你一个值,可以是一个空字符串(字符串。如果需要比较,则为空)。
我会使用以下方法,不会太担心:
employee.FirstName = sqlreader["columnNameForFirstName"].ToString();
你需要检查IsDBNull:
if(!SqlReader.IsDBNull(indexFirstName))
{
employee.FirstName = sqlreader.GetString(indexFirstName);
}
这是检测和处理这种情况的唯一可靠方法。
我把这些东西包装到扩展方法中,如果列确实为空,则倾向于返回默认值:
public static string SafeGetString(this SqlDataReader reader, int colIndex)
{
if(!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
现在你可以这样调用它:
employee.FirstName = SqlReader.SafeGetString(indexFirstName);
而且您再也不用担心异常或空值了。