如果我有类似于以下的代码:
while(myDataReader.Read())
{
myObject.intVal = Convert.ToInt32(myDataReader["mycolumn"] ?? 0);
}
它抛出错误:
对象不能从 DBNull 转换为其他类型。
定义intVal
为可为空的 int 不是一种选择。有没有办法让我做到以上?
如果我有类似于以下的代码:
while(myDataReader.Read())
{
myObject.intVal = Convert.ToInt32(myDataReader["mycolumn"] ?? 0);
}
它抛出错误:
对象不能从 DBNull 转换为其他类型。
定义intVal
为可为空的 int 不是一种选择。有没有办法让我做到以上?
这是另一种选择:
while (myDataReader.Read())
{
myObject.intVal = (myDataReader["mycolumn"] as int? ?? 0);
}
你可以使用扩展方法吗?(写在我的头上)
public static class DataReaderExtensions
{
public static T Read<T>(this SqlDataReader reader, string column, T defaultValue = default(T))
{
var value = reader[column];
return (T)((DBNull.Value.Equals(value))
? defaultValue
: Convert.ChangeType(value, typeof(T)));
}
}
你会像这样使用它:
while(myDataReader.Read())
{
int i = myDataReader.Read<int>("mycolumn", 0);
}
你可以简单地使用Int32.Tryparse
吗?
int number;
bool result = Int32.TryParse(myDataReader["mycolumn"].ToString(), out number);
根据MSDN,number
如果转换失败,将包含 0
怎么样:
object x = DBNull.Value;
int y = (x as Int32?).GetValueOrDefault(); //This will be 0
或者在你的情况下:
int i = (myDataReader["mycolumn"] as Int32?).GetValueOrDefault();
为什么不使用空合并运算符(DBNull.Value
!= null
)以外的东西:
int i = myDataReader["mycolumn"] == DBNull.Value ?
Convert.ToInt32(myDataReader["mycolumn"]) :
0;
你总是可以用一个简洁的扩展方法把它包装起来:
public static T Read<T>(this DataReader reader, string column, T defaultVal)
{
if(reader[column] == DBNull.Value) return defaultVal;
return Convert.ChangeType(reader[column], typeof(T));
}
不,仅适用于空值。
对检查 DBNull 并返回默认值的对象的扩展方法怎么样?
//may not compile or be syntactically correct! Just the general idea.
public static object DefaultIfDBNull( this object TheObject, object DefaultValue )
{
if( TheObject is DBNull )
return DefaultValue;
return TheObject;
}