Error: Object reference not set to an instance of an object, how to solve?

Posted on

Question :

I have the ChamadaEfetuada(MAluno) : bool method that verifies that the call was made for a given student, this method is used in another method ChamadaEfetuada() : bool that instead of checking if the call was made to a single student, it checks all students at once, and it only returns true if the call has been made to all students.

But I’m getting an error in my ChamadaEfetuada() : bool method with the following message:

  

Object reference not set to an instance of an object.

The error occurs on this line:

alunos[i].IdAluno = Convert.ToInt32(registro["id_aluno"]);

The compiler says that the problem is in my array alunos .

Complete method code ChamadaEfetuada(MAluno) : bool :

public bool ChamadaEfetuada(MAluno aluno) 
        {
            string query = "SELECT id_aluno FROM Lista_presenca WHERE id_aluno = " + aluno.IdAluno + " AND data = '" + this.Hoje() + "'";

            DadosConexao dados_conexao = new DadosConexao();

            SQLiteConnection conexao = this.conexao.Conexao;
            conexao.Open();

            SQLiteCommand command = conexao.CreateCommand();
            command.CommandText = query;            

            SQLiteDataReader registro = command.ExecuteReader();

            bool existe_registro = registro.HasRows;

            conexao.Close();

            return existe_registro;            
        }

Complete method code ChamadaEfetuada() : bool :

public bool ChamadaEfetuada() 
        {
            string query = "SELECT id_aluno FROM Alunos";

            int total_alunos = 0, alunos_chamada_efetuada = 0;

            DadosConexao dados_conexao = new DadosConexao();

            SQLiteConnection conexao = this.conexao.Conexao;
            conexao.Open();

            SQLiteCommand command = conexao.CreateCommand();
            command.CommandText = query;

            SQLiteDataReader registro = command.ExecuteReader(); //Obtem os IDs de todos os alunos

            MAluno[] alunos = new MAluno[registro.FieldCount];

            total_alunos = registro.FieldCount;

            int i = 0;            

            while (registro.Read())
            {                
                alunos[i].IdAluno = Convert.ToInt32(registro["id_aluno"]); //Popula o atributo IdAluno do objeto alunos com os IDs obtidos pela query. Porem aqui acontece o erro.
                i++;                
            }

            conexao.Close();

            for (i = 0; i < registro.FieldCount; i++)
            {
                if (this.ChamadaEfetuada(alunos[i])) 
                {
                    alunos_chamada_efetuada++;
                }
            }

            if (alunos_chamada_efetuada == total_alunos)
                return true;
            else
                return false;
        }

The above two methods are part of my BLLListaPresenca class.

    

Answer :

I do not know if I’m going to help you, because these error messages in Portuguese get in the way and there is missing information that could indicate why the error occurred.

I’ll kick you do not want FieldCount , anyway it does not matter how many columns it has. It matters how many lines it has. And this information is not available. And then you can not use an array (actually almost always using an array , you are making a mistake). You would have to use a list to go by adding the available rows in it. You can even use the array , but the game is so big that I will not even quote it.

To tell you the truth I have my doubts if creating this array or list is really necessary. It’s even in this code, but it has several problems.

The code is very confusing, uses wrong techniques, unnecessary codes, methods do more than they should, are repetitive, unreliable, insecure, fairly inefficient and in this way, one method to call the other should be the last thing to do. It would need a complete restructuring.

    

Following the bigown recommendations I made the changes to my ChamadaEfetuada() : bool method and removed the ChamadaEfetuada(MAluno) : bool method. Replace the array MAlunos[] alunos with a List<T> list and made the implementation of the rule that is check if the call was already made to all the students in my method, I also correctly implemented the parameters of my SQLiteCommand to perform searches.

Below is the ChamadaEfetuada() : bool (restructured) method that is the solution of the above problem:

public bool ChamadaEfetuada() 
{   
    /*Listas*/
    var alunos = new List<MAluno>();
    var alunos_chamada = new List<MAluno>();

    /*Prepara a conex√£o*/            
    SQLiteConnection conexao = this.conexao.Conexao;
    conexao.Open();

    using (SQLiteCommand command = conexao.CreateCommand()) 
    {                
        command.CommandText = "SELECT id_aluno FROM Alunos";

        SQLiteDataReader registro = command.ExecuteReader();

        if (registro.HasRows)
        {
            while (registro.Read())
            {
                alunos.Add(new MAluno
                {
                    IdAluno = Convert.ToInt32(registro.GetValue(0))
                });
            }
        }
        else
        {
            conexao.Close();
            return false;
        }

        conexao.Close();
    }

    conexao.Open();

    using (SQLiteCommand command = conexao.CreateCommand()) 
    {                
        foreach (var aluno in alunos) 
        {                    
            command.Parameters.Add("id_aluno", DbType.Int32).Value = aluno.IdAluno;
            command.Parameters.Add("data", DbType.String).Value = this.hoje;
            command.CommandText = "SELECT id_aluno FROM Lista_Presenca WHERE id_aluno = ? AND data = ?";

            SQLiteDataReader registro = command.ExecuteReader();

            if (registro.HasRows)
            {
                registro.Read();

                alunos_chamada.Add(new MAluno
                {
                    IdAluno = Convert.ToInt32(registro.GetValue(0))
                });                        
            }
            else 
            {
                conexao.Close();
                return false;
            }

            registro.Close();            
        }

        conexao.Close();
    }

    return (alunos.Count == alunos_chamada.Count);
}

    

Leave a Reply

Your email address will not be published. Required fields are marked *