[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4751
  • Last Modified:

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

0
gjok
Asked:
gjok
  • 5
  • 5
  • 2
  • +2
1 Solution
 
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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
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
 
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

Featured Post

[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

  • 5
  • 5
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now