有更好/更清晰的方法来做这件事吗?
int stockvalue = 0;
if (!Convert.IsDBNull(reader["StockValue"]))
stockvalue = (int)reader["StockValue"];
有更好/更清晰的方法来做这件事吗?
int stockvalue = 0;
if (!Convert.IsDBNull(reader["StockValue"]))
stockvalue = (int)reader["StockValue"];
我认为最短的是:
int stockvalue = (reader["StockValue"] as int?) ?? 0;
解释:
int? stockvalue = reader["StockValue"] as int?
。 - stevehipwellint x = (int)obj
,当列的类型更改时,您的代码将会出错,因此您需要将其更正为 double x = (double)obj
。@JohnSaunders 的警示是正确的,因为使用 as int?
方法将悄无声息地吞噬这种变化;只有当有人注意到一个不应该存在的零值时,您才能发现它。 - phoog我处理这个问题的方式是
int? stockvalue = reader["StockValue"] as int?;
非常简单、清晰且只有一行代码。如果由于某种原因我绝对不能有空值(通常来说我认为这是不好的理由,因为我更想知道一个值是否有意义,或者是否对原始类型进行了初始化),那么我会这样做:
int stockvalue = (reader["StockValue"] as int?).GetValueOrDefault(-1);
(int?) reader["ColumnName"]
时遇到了一个异常,于是开始寻找正确的做法。这应该被接受为答案。 - Anloint? stockvalue = reader.GetValue<int?>("StockValue");
这是一个扩展方法(根据您的需求进行修改):
public static class ReaderHelper
{
public static bool IsNullableType(Type valueType)
{
return (valueType.IsGenericType &&
valueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
}
public static T GetValue<T>(this IDataReader reader, string columnName)
{
object value = reader[columnName];
Type valueType = typeof(T);
if (value != DBNull.Value)
{
if (!IsNullableType(valueType))
{
return (T)Convert.ChangeType(value, valueType);
}
else
{
NullableConverter nc = new NullableConverter(valueType);
return (T)Convert.ChangeType(value, nc.UnderlyingType);
}
}
return default(T);
}
}
int? stockvalue = (int?)(!Convert.IsDBNull(result) ? result : null);
以下是一种可能的解决方案,以确保DBNull可以传递到您的代码中。对于我们的团队,最佳实践是尽量避免在数据库中使用NULL列,除非确实需要。处理它需要更多的编码开销,有时候重新思考问题会使其不再需要。
int?
这种方式,这样您就可以有一个默认值为 null 而不是 0。由于 stockvalue 的结果可能是 0,因此不会混淆数据库是否为 0 或 null。例如,像这样(可空之前),我们有一个默认初始化为 -1 来表示没有分配值。就我个人而言,我认为这有点危险,因为如果您忘记将其设置为 -1,则可能存在数据损坏问题,难以跟踪。int? stockvalue = null;
if (!Convert.IsDBNull(reader["StockValue"]))
stockvalue = (int)reader["StockValue"];
//Then you can check
if(stockValue.HasValue)
{
// do something here.
}
DBNull
仍然需要进行一些检查才能转换为 null
。 - Jon Seigel虽然引用reader["StockValue"]
很方便,但并不是很高效。它也没有强类型检查,因为返回的类型是object
。
相反,在您的代码中,可以像这样进行操作:
int stockValueOrdinal = reader.GetOrdinal("StockValue");
int? stockValue = reader.IsDbNull(stockValueOrdinal) ?
null :
reader.GetInt32(stockValueOrdinal);
int stockvalue = reader["StockValue"] != DbNull.Value ? Convert.ToInt32(reader["StockValue"]) : 0;
这是一种方法。
int stockvalue = Convert.IsDbNull(reader["StockValue"]) ? 0 : (int)reader["StockValue"];
你也可以使用 TryParse
int stockvalue = 0
Int32.TryParse(reader["StockValue"].ToString(), out stockvalue);
请告诉我们哪种方式适合您
你可以直接在数据库查询中进行此转换,从而完全避免特殊情况。
但是,除非您可以在代码中一致地使用该形式,否则我不会称其为“更清晰”,因为您将通过从数据库返回“0”而不是NULL来丢失信息。
不一定。你可以将它封装在一个方法中:
public int getDBIntValue(object value, int defaultValue) {
if (!Convert.IsDBNull(value)) {
return (int)value;
}
else {
return defaultValue;
}
并像这样调用它:
stockVaue = getDBIntVaue(reader["StockValue"], 0);
或者您可以在查询中使用coalesce
来强制返回的值为非空。
编辑 - 根据收到的评论纠正了愚蠢的代码错误。
getDBIntValue
方法会尝试从 reader["StockValue"]
中提取 int
,无论传入的值是什么。而且你的参数列表中有一个关键字 default
,这是不能编译通过的(你需要将其改为 @default
,或者更好的方法是更改名称)。 - Dan Tao