Is there a better/cleaner way to do this?
int stockvalue = 0;
if (!Convert.IsDBNull(reader[\"StockValue\"]))
stockvalue = (int)reader[\"StockValue\"];
The way I handle this is
int? stockvalue = reader["StockValue"] as int?;
Very simple, clean and one line. If for some reason I absolutely can't have a null value (which I find poor reasoning for usually since I'd rather know if a value has meaning or if it was unitialized for a primitive type) I would do:
int stockvalue = (reader["StockValue"] as int?).GetValueOrDefault(-1);
Yes you can use int?
This way you can have a default value of null instead of 0. Since the result of stockvalue could potentially be 0 there isn't confusion as to whether the database was 0 or null. For instance like this (pre nullable) we had a default initialization of -1 to represent no value was assigned. Personally, I thought this was a little dangerous because if you forget to set it to -1, there is a data corruption issue that can be really difficult to track down.
http://msdn.microsoft.com/en-us/library/2cf62fcy(VS.80).aspx
int? stockvalue = null;
if (!Convert.IsDBNull(reader["StockValue"]))
stockvalue = (int)reader["StockValue"];
//Then you can check
if(stockValue.HasValue)
{
// do something here.
}
The shortest (IMHO) is:
int stockvalue = (reader["StockValue"] as int?) ?? 0;
Explanation:
int? stockValue = reader["StockValue"] == null || reader["StockValue"] == DBNull.Value ? null : (int?)reader["StockValue"];
You could do this conversion directly in your DB-query, thus avoiding the special case alltogether.
But I wouldn't call that 'cleaner', unless you can consistently use that form in your code, since you would lose information by returning '0' instead of NULL from the DB.
While it's convenient to reference reader["StockValue"]
, it's not very efficient. It's also not strongly-typed, as it returns type object
.
Instead, within your code, do something like this:
int stockValueOrdinal = reader.GetOrdinal("StockValue");
int? stockValue = reader.IsDbNull(stockValueOrdinal) ?
null :
reader.GetInt32(stockValueOrdinal);
Of course, it's best to get all of the ordinals at one time, then use them throughout the code.