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);
}