我不断收到错误System.InvalidCastException:指定的强制转换无效。在运行时。数据库中的RewardJoinType可以为null。
这是演员阵容失败的代码行:
c.rewardJoinType = (RewardJoinType)reader.GetInt16();
'reader.GetInt16()'引发了类型'System.InvalidCastException'short {System.InvalidCastException}
的异常在课堂上,我有以下几行代码:
private RewardJoinType? rewardJoinType;
......其他一些代码
c.rewardJoinType = (RewardJoinType?)reader.GetInt16();
......其他一些代码
conn.AddParam("@rewardJoinType", (int?)rewardJoinType);
......其他一些代码
public RewardJoinType? RewardJoinType
{
get { return rewardJoinType; }
set { rewardJoinType = value; }
}
这是枚举本身
public enum RewardJoinType
{
Auto,
Manual
}
是因为默认情况下枚举是Int32,即使我已经将它作为可空的,它也无法转换为null的Int16?
我们在读者中处理Int16的DBNull:
public short GetInt16()
{
columnIndex++;
return reader.IsDBNull(columnIndex) ? (short)0 : reader.GetInt16(columnIndex);
}
答案 0 :(得分:5)
当数据库值为null时,实际返回的是DBNull的实例,而不是“null”,并且DBNull不能转换为其他任何内容。我为这些情况做的是编写一个帮助方法,将GetXXX()的返回值转换为null或可以为null的结构。类似的东西:
static T? ConvertIfNotDBNull<T>(object o, Converter<object, T> converter) where T : struct {
return o is DBNull ? (T?)null : converter(o);
}
并传入Convert.ToInt32或类似转换器。
如果您使用附加的调试器运行它,可以帮助确定它抛出异常的确切位置,然后查看它尝试强制转换的内容。
答案 1 :(得分:1)
好的,我的错误。读者必须是GetInt8(),它在我们的代码中转换为返回一个字节,因为DB字段的类型为tinyInt
答案 2 :(得分:0)
数据库空值不是代码空值,因此您需要类似这样的内容
obj val = reader.GetValue();
if(val != DbNull.Value) c.RewardJoinType = (RewardJoinType)val;