Loading a Null value into an int variable

I am loading values from a database record into a class. One of the class properties is an int, which corresponds to an int fiel in the database.
However, sometimes the DB value in null, which causes an exception when assigning the value to the class property.

I know I can set defaults on the database, but I am more curious to learn how to handle this kind of problem for future reference.
What is the standard proceure for dealing with this problem?

Thanks
private int? _sslPort;
 
public int? SSLPort
{
  get { return _sslPort; }
  set { _sslPort = value; }
}
 
Domain myDomain = new Domain();
myDomain.SSLPort = int.Parse(dr["SSLPort"].ToString()) ?? 0; // Error
myDomain.SSLPort = Convert.ToInt32(dr["SSLPort"]) ?? 0; // Error

Open in new window

LVL 2
gjokAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

YiogiCommented:
because your database null is DBNull.Value not null. It's a different datatype. You should check if the value is DBNull.Value and if it is then not try to convert it but simply assign null to your int. You need of course an IF THEN ELSE END IF statement.
0
Jaime OlivaresSoftware ArchitectCommented:
will be better something like:

if (dr["SSLPort"].ToString()==DBNull.Value)
      myDomain.SSLPort = null;
else
     myDomain.SSLPort= int.Parse(dr["SSLPort"].ToString());

but Parse is a dangerous method, you can use tryparse instead:

myDomain.SSLPort = null;  // always null at begining
try {  myDomain.SSLPort= int.Parse(dr["SSLPort"].ToString());  }
catch { }


int.TryParse(

0
Jaime OlivaresSoftware ArchitectCommented:
Sorry, typo, ignore the last line (TryParse), it wont work with a nullable type. use try/catch instead as shown.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

YiogiCommented:
You shouldn't convert to string. DBNull.Value cannot be converted to string it will throw an exception right there.
0
Jaime OlivaresSoftware ArchitectCommented:
that's why I put a try/catch, after setting null value as default
0
YiogiCommented:
This will throw an exception
if (dr["SSLPort"].ToString()==DBNull.Value)

It should be
if (dr["SSLPort"]==DBNull.Value)

You don't use a try catch there. And you shouldn't have to. And yes I'd prefer int.TryParse. Usage is
string numberToConvert;
int convertedNumber;

if (int.TryParse(numberToConvert, convertedNumber)) {
  // This is a valid number do what you want
}
else {
 // This is not a number do what you want
}

But none of those are needed. If his datatype is int in his dataset he doesn't need any convertion to string and from there to a number. He can simply do:
int yourNumber = dr["SSLPort"];
0
Jaime OlivaresSoftware ArchitectCommented:
about this:
>>This will throw an exception
>>if (dr["SSLPort"].ToString()==DBNull.Value)
>>It should be
>>if (dr["SSLPort"]==DBNull.Value)

you are right, I copy/pasted without care.

about this:
>>And yes I'd prefer int.TryParse....
you can't, tryparse won't work with a nullable type.

about this:
>>int yourNumber = dr["SSLPort"];
it won't work without proper casting, maybe with:
int yourNumber = (int)dr["SSLPort"];
but just assuming that SSLPort is an integral type, if not, it will throw a exception anyway because could be also a string type.

0
YiogiCommented:
Yes but he doesn't need a nullable type. He only has it nullable so he can accept database nulls, or at least I assume. But it's not the same type. Anyway enough arguing, please accept my apologies if I offended you.

Going to bed it's past 3am here.
0
Expert1701Commented:
*NOT FOR POINTS* as this is only an extension of Yiogi's first post, but here is how I regularly do it:

  myDomain.SSLPort = dr["SSLPort"]==DBNull.Value ? 0 : (int)dr["SSLPort"];
0
Jaime OlivaresSoftware ArchitectCommented:
If you use this approach:
myDomain.SSLPort = dr["SSLPort"]==DBNull.Value ? 0 : (int)dr["SSLPort"];

then nullable type is unuseful, it is not the same 0 than Null
0
Expert1701Commented:
*NOT FOR POINTS* but again, if you wanted to use the nullable type, you could do it as follows, instead of setting the undefined port to 0.

  myDomain.SSLPort = (int?)(dr["SSLPort"] == DBNull.Value ? null : dr["SSLPort"]);
0
gjokAuthor Commented:
Expert1701,
You say "*NOT FOR POINTS* ", but this:
myDomain.SSLPort = dr["SSLPort"]==DBNull.Value ? 0 : (int)dr["SSLPort"];
...is EXACTLY wat I have been trying to acheive!

and your other comment:
myDomain.SSLPort = (int?)(dr["SSLPort"] == DBNull.Value ? null : dr["SSLPort"]);
...is the cherry on the cake!!

As shown in my original snippet, I was tryiing for a one-line solution, because I am reading in about 30 fields, which would be messy if using if/else or try/catch blocks.
A one-line statement makes the overall code easy to read - in one screen without paging-up/down.

I thank the rest of you but I feel compelled to assign the points to Expert1701.
0
YiogiCommented:
gjok I have absolutely no problem who you assign the points to. You don't need try catch statements though just an if statement but yes his solution is simpler. What I proposed is:

if (dr["SSLPort"]==DBNull.Value) {
    myDomain.SSLPort = null;
}
else {
    myDomain.SSLPort = (int)dr["SSLPort"];
}

That though is exactly what he is doing in one line not 4 so ya why not give him the points.

Glad I could have helped.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MrEyesCommented:
Another alternative to assigning myDomain.SSLPort to 0 when a DBNull value is found, is to actually use the .NET nullable int type.

As an example, have a look at the following code:

##################### SNIP #####################
class Program
    {
        static void Main(string[] args)
        {
            DataStore ds = new DataStore();

            //If uncommented the next line creates a compiler
            //error "Cannot convert null to 'int' because it is a value type"
            //ds.NonNullableInt = null;

            //However this does not
            ds.NullableInt = null;

            //from here on you can use the class data within the application
            if (ds.NullableInt == null)
            {
                Console.WriteLine("Value is null");
            }
            else
            {
                Console.WriteLine("Value is {0}", ds.NullableInt);
            }

            //you can obviously put none null value is
            ds.NullableInt = 42;

            if (ds.NullableInt == null)
            {
                Console.WriteLine("Value is null");
            }
            else
            {
                Console.WriteLine("Value is {0}", ds.NullableInt);
            }

            //while on the subject of nulls, you can also use the null
            //coalescing operator to manage program flow.  For example
            //this will set the value of X to the value of nullableint if
            //this is not null, otherwise it will be -1
            int x = ds.NullableInt ?? -1;
        }
    }
##################### SNIP #####################

So if you case, you would change the Domain class variable/accessor declarations to "int?" and then when reading the DB data into the class use the following:

Domain dom = new Domain();
dom.SSLPort = (int?)(data["SSLPort"] == DBNull.Value ? null : data["SSLPort"]);

EDIT : Damn ;) I didn't notice the reply from Expert1701, ahh well, might as well leave the post now
0
gjokAuthor Commented:
Difficult decision as you have all been so helpful, but as Expert1701 said:
"this is only an extension of Yiogi's first post", so seeing as he didnt want the points I think they should go to Yiogi.

When I was writing my original question I had written that I was looking for a one-line solution, but I removed that part before I posted it, as I was trying to keep the question as short as possible and I hoped the attempts in my snippet would send the same message.

Thanks also to jaime_olivares and MrEyes.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.