Dris Dris - 3 months ago 17
SQL Question

Create buttons from database - System.NullReferenceException occured

This code worked yesterday, but today when I start, i got this error.
I dont know what happened, the database still connected.

The code:

private void LoginFS_Load(object sender, EventArgs e)
{

SQLFunctions Lgn = new SQLFunctions();
Lgn.ConnectionToday();

SqlCommand cmd = new SqlCommand();
cmd.Connection = SQLFunctions.conn;

int NumOfButtons = 50;

for (int i = 1; i <= NumOfButtons; i++)
{
Button btn = new Button();
{
btn.Tag = i;
btn.Dock = DockStyle.Fill;
btn.Margin = new Padding(10, 10, 10, 10);

cmd.CommandText = "SELECT username FROM Login where id='" + btn.Tag + "'";

btn.Text = cmd.ExecuteScalar().ToString(); // <= ERROR
//ERROR: An unhandled exception of type 'System.NullReferenceException' occurred in. Additional information: Object reference not set to an instance of an object.
string btn_name = cmd.ExecuteScalar().ToString();
btn.Name = btn_name.ToString();

btn.Click += delegate
{
pass_txt.Clear();
username_txt.Text = btn_name;
username_lbl.Text = btn_name;
username_lbl.Visible = true;
pass_txt.ReadOnly = false;
};

}
users_table.Controls.Add(btn);

}
SQLFunctions.conn.Close();
}


What should I do, or why got this error?
Thanks

Answer

You are trying to use something that can exist, but also, can not...

cmd.CommandText = "SELECT username FROM Login where id='" + btn.Tag + "'";
btn.Text = cmd.ExecuteScalar().ToString();

You must verify if the query returns something, BEFORE you try to use it...

cmd.CommandText = "SELECT username FROM Login where id='" + btn.Tag + "'";
var Text = cmd.ExecuteScalar();
if(Text != null) {
  //do your things here
}

Regarding the problem of 50 buttons, this happens because you are doing a looping to 50, and creating the buttons no matter what:

for (int i = 1; i <= NumOfButtons; i++)
{
    Button btn = new Button(); //<= here you create the button

If you want to create buttons ONLY if the buttons exist in the database, you could do something like this:

for (int i = 1; i <= NumOfButtons; i++)
{
    cmd.CommandText = "SELECT username FROM Login where id='" + i.ToString() + "'";
    var Text = cmd.ExecuteScalar();
    if(Text != null) {
        Button btn = new Button();
        {
            //...
        }
    }
}

This way, you creates the button ONLY if it exists in database. But going even further, maybe you should consider putting the query before the looping, querying all the buttons that exist and than doing the looping for them...