Domanda

How come I get an invalid cast exception when trying to set a NULL value returned from the database inside Comments which is of type Int32.

I am trying to replace this:

                try
                {
                    objStreamItem.Comments = (Int32)sqlReader["Comments"];
                    if (objStreamItem.Comments > 0) { 
                        listComments = Comment.GetAll(objStreamItem.Id);

                    }
                }
                catch (InvalidCastException)
                {
                    // Execute if "Comments" returns NULL
                    listComments = null;
                    objStreamItem.Comments = 0;
                }

With this:

Comments = ((Int32?)sqlReader["Comments"]) ?? 0

The two are in different contexts, but you should get the idea. Instead of using a try catch block I am trying to solve this in a more elegant way.

Thanks.

UPDATE

It is stored as a nullable integer in the database.

    public int? Comments
    {
        get;
        set;
    }

I just want to thank everyone who answered or posted on this question, everything was very informative. thanks!

È stato utile?

Soluzione

I suppose a ternary expression is the way to go here

objStreamItem.Comments = sqlReader["Comments"] is DBNull ? 0 : (Int32)sqlReader["Comments"] ;

You could also store the return value of sqlReader["Comments"] in a variable first to shorten the expression

var comments = sqlReader["Comments"];
objStreamItem.Comments = comments is DBNull ? 0 : (Int32)comments;

Altri suggerimenti

Your SQL reader is returning DBNull when the value is null; There's no conversion from DBNull to int?, and the null-coalescing operator doesn't recognize DBNull.Value as something that needs to be coalesced.

EDIT 3

(Another problem with your original code: It will assume that "Comments" returned null if "Comments" is non-null but GetAll() throws an InvalidCastException.)

As hvd points out, you can use the as operator with nullable types:

objStreamItem.Comments = sqlReader["Comments"] as int?;
listComments = (objStreamItem.Comments ?? 0) > 0 ? Comment.GetAll(objStreamItem.ID) : null;

You could save yourself from all of this, however, if you simply defined Comment.GetAll() to return an empty list or a null reference when the ID you pass to it has no comments.

The ?? operator checks for null, but sqlReader["Comments"] won't ever be null. It will either be an Int32, or a DBNull. You can cast null to Int32?, but you cannot do so with DBNull.Value. You can use sqlReader["Comments"] as Int32? instead, which checks if the result can be converted to Int32, and if not, assigns null.

That statement tries to perform the cast before coalescing the values. You need to add parenthesis. Judging by your example above, it also looks like the field is an int rather than an int?:

Comments = (Int32)(sqlReader["Comments"] ?? 0);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top