DataRow обнуляется в Foreach - PullRequest
0 голосов
/ 07 февраля 2020

Я написал метод для загрузки данных пользователя из БД, и моя строка данных DataRow обнуляется, поэтому я не могу прочитать эти данные. Где я потерял власть на линии? Как я могу прочитать набор данных, используя C#?

private void _Load(string ALogin) {
    MySqlCommand sqlQuery = new MySqlCommand($"select u.login, u.nome, u.tipo, u.ativo, m.id, m.nome, m.crm, m.habilitado FROM sis_usuarios u LEFT JOIN sis_medicos m ON u.medico = m.id WHERE u.login = \"{ALogin}\"", _dbConn.GetConnection());
    sqlQuery.Prepare();
    MySqlDataAdapter da = new MySqlDataAdapter(sqlQuery);
    DataTable tabela = new DataTable();

    da.Fill(tabela);

    if (tabela.Rows.Count != 1) {
        throw new Exception($"Usuário não encontrado! \nLogin: {ALogin}");
    }

    foreach(DataRow linha in tabela.Rows) {
        this.Nome = linha["nome"].ToString();
        this.Login = linha["login"].ToString();
        if(!DBNull.Value.Equals(linha)) {
            this.Medico = new MedicoModel(Int32.Parse(linha["m.id"].ToString()),
                                     linha["m.nome"].ToString(),
                                     linha["m.crm"].ToString(),
                                     Boolean.Parse(linha["m.habilitado"].ToString()));
            _Mode = Mode.EDT;
        }
    }
}

VisualStudio 2019 C#

Ответы [ 5 ]

1 голос
/ 07 февраля 2020

Вы не можете проверить всю строку с DbNull. Вам необходимо проверить отдельные поля или, по крайней мере, в этом контексте, по крайней мере, поле идентификатора.

Существует DataRow.IsNull (имя поля)

if(!linha.IsNull("id")) {
    this.Medico = new MedicoModel(Int32.Parse(linha["id"].ToString()),
                             linha["nome"].ToString(),
                             linha["crm"].ToString(),
                             Boolean.Parse(linha["habilitado"].ToString()));

Обратите внимание, что префикс псевдонима не требуется, когда данные попадают в строки с данными.

Сказал, что в вашем запросе есть еще одна серьезная проблема. Вы объединяете строку для создания команды sql. Это хорошо известная проблема, приводящая к хакерским атакам Sql и ошибкам синтаксического анализа. Вы должны использовать параметры как здесь:

MySqlCommand sqlQuery = new MySqlCommand(@"select u.login, u.nome, 
   u.tipo, u.ativo, m.id, m.nome, m.crm, m.habilitado 
   FROM sis_usuarios u LEFT JOIN sis_medicos m ON u.medico = m.id 
   WHERE u.login = @login", _dbConn.GetConnection());
sqlQuery.Parameters.Add("@login", MySqlDbType.VarChar).Value = ALogin;
0 голосов
/ 07 февраля 2020

Вы можете проверить свои поля на null и после проверки вы можете безопасно создать объект:

var id = linha["id"];
var nom = linha["nome"];
var crm = linha["crm"];
var habilitado = linha["habilitado"];

if (id != null && nom != null &&  crm != null && habilitado != null) 
{
    this.Medico = new MedicoModel((int)id, nom.ToString(), 
        crm.ToString(), (bool)habilitado); 
}
0 голосов
/ 07 февраля 2020

Вам необходимо изменить значение с

if(!DBNull.Value.Equals(linha)) {

на

if(!DBNull.Value.Equals(linha["nome"])) {

, поскольку, как упоминал Стив в комментариях, DBNull.Value следует использовать со значениями столбцов, а не строк

0 голосов
/ 07 февраля 2020

Вам нужно изменить в двух местах. 1. измените условие If. См. Документацию DBNull 2. удалите m. из имен полей

if (!DBNull.Value.Equals(linha["id"])) 
{
    this.Medico = new MedicoModel(Int32.Parse(linha["id"].ToString()),
                               linha["nome"].ToString(),
                               linha["crm"].ToString(),                                                                                 
                               Boolean.Parse(linha["habilitado"].ToString()));
}
0 голосов
/ 07 февраля 2020

Вместо linha["m.crm"] попробуйте использовать linha["crm"].

m.crm, используемое в операторе SQL, является лишь частью команды SQL select, выполняемой на сервере SQL, и результат этого выбора (набор данных) содержит crm без псевдонима таблицы m. в качестве имени столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...