views:

94

answers:

6

I have CustomerID declared as

int? CustomerID=null;

I am checking null values while reading DataReader

Id = reader["CustomerId"] is DBNull ? null :Convert.ToInt32(reader["CustomerID"]);

It is throwing

 Type of conditional expression cannot be determined because there 
  is no implicit conversion between '<null>' and 'int'

What is the problem with the Conversion?

+3  A: 

Change your conditon to

  reader["CustomerId"] ==  DBNull.Value
Aliostad
True, though this isn't what's causing the specific error.
John M Gant
+1  A: 

A ?: conditional expression cannot evaluate to two different types on the true and false condition. I think a cast (int?)null should work.

Pratik
Yes, casting will solve the problem: Id = reader["CustomerId"] is DBNull ? (int?)null : Convert.ToInt32(reader["CustomerID"]);
Pavel Morshenyuk
Well i don't like casting nulls. reader.IsDbNull is much cleaner.
Yves M.
I'm talking about "True" part of conditional expression. Not about checking reader if it is DBNull.
Pavel Morshenyuk
+1, this would address the specific error message, though it's not the best solution in my opinion.
John M Gant
+4  A: 

I think you need to do it this way:

if(! reader.IsDBNull(reader.GetOrdinal("CustomerId"))
{
   Id = Convert.ToInt32(reader["CustomerID"]);
}
else
{
   Id = NULL;
}

You need to use the .IsDBNull method on the reader to determine ahead of time if a column is NULL - if it is, don't even read the value from the reader.

marc_s
+1, better solution. If you don't like the multi-line approach, you might be able to add an extension method to the data reader class to allow single-line syntax in your code.
John M Gant
Is there an overload of IsDBNull that takes the column name? I can only find the int version on MSDN: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.isdbnull.aspx
Justin Niessner
@Justin Niessner: no, sorry - that would be my own extension method.... updated my answer
marc_s
+2  A: 

The problem (assuming that Id is declared properly) is that the conditional statement infers the result type from the true result. In your case, that type is null. It then will try to cast the second type to the same as the first...and there is no cast from int to null.

The solution is to cast the true expression to the desired type:

Id = reader["CustomerId"] == DBNull.Value ?
    (int?) null :
    Convert.ToInt32(reader["CustomerID"]);
Justin Niessner
+1 to reverse (uncommented) downvote. This is the correct answer to "What is the problem with this conversion."
John M Gant
A: 

What's happening is your code is incorrectly evaluating and trying to do the Convert function.

Its readding reader["CustomerId"] is DBNull which it isn't its really a DBNull.Value so then it attempts to do Convert.ToInt32("<null>") and crashes. You need to fix your if statement, and add a (int ?) cast.

It should be:

 Id = reader["CustomerId"] is DBNull.Value ? (int?) null :Convert.ToInt32(reader["CustomerID"]);
Nix
will cause the same error. null cant be converted to int?
Jamiec
Tech, it would produce a new error, but his original error was because he was attempting to do Convert.ToInt32("<Null>");
Nix
A: 

Try this

Id = reader["CustomerId"] is DBNull ? (int?)null : Convert.ToInt32(reader["CustomerID"]);

the types of both parts of the ?: need to be explicit

Kleinux
+1 to reverse (uncommented) downvote. This is the correct answer to "What is the problem with this conversion."
John M Gant
Yes it is working for me
Amit