Возникло исключение: «System.Collections.Generic.KeyNotFoundException» в mscorlib.dll при использовании запроса SELECT. - PullRequest
0 голосов
/ 14 мая 2018
try
{
    string connString = "server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8";
    MySqlConnection conn = new MySqlConnection(connString);
    conn.Open();
    MySqlCommand cmd = new MySqlCommand("SELECT School_Name FROM schools WHERE School_ID=@id", conn);
    cmd.Parameters.AddWithValue("@id", "1");
    var schoolName = cmd.ExecuteScalar();
    label1.Text = schoolName.ToString();
    conn.close();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

Приведенный выше код возвращает исключение Выдается исключение: 'System.Collections.Generic.KeyNotFoundException' в mscorlib.dll

Однако всякий раз, когда я использовал запрос, такой как ВСТАВИТЬ, ОБНОВИТЬ и УДАЛИТЬ это работает просто отлично .Как и в приведенном ниже коде:

try
{
    string connString = "server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8";
    MySqlConnection conn = new MySqlConnection(connString);
    conn.Open();
    MySqlCommand cmd = new MySqlCommand("INSERT INTO schools(School_Name,School_Address) VALUES(@name,@address)", conn);
    cmd.Parameters.AddWithValue("@name", "Sample Name");
    cmd.Parameters.AddWithValue("@address", "Sample Address");
    cmd.ExecuteNonQuery();
    label1.Text = "Success";
    conn.Close();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

Итак, в основном моя проблема заключается в следующем:

  1. Первый блок кода работает просто отлично, если используется в Xamarin.Forms (проверено в Android).Я могу ВЫБРАТЬ из базы данных.
  2. Первый блок кода не работает, если используется в приложении Windows Forms , и возвращает указанное исключение.И Xamarin.Forms, и Windows Forms App работают на C #, поэтому я точно не знаю, почему это происходит.
  3. Второй блок кода прекрасно работает как в Xamarin.Forms , так и Приложение Windows Forms .
  4. По сути, я могу выполнить любой запрос SQL, но не SELECT.

1 Ответ

0 голосов
/ 14 мая 2018

Прежде всего, ваш код может оставить соединение открытым в случае возникновения исключения.conn.Close() следует переместить в блок finally.Во-вторых, для запроса значений вы должны использовать метод cmd.ExecuteReader(), который вернет объект MySqlDataReader;Чтобы утилизировать его, вы можете использовать конструкцию using().Метод ExecuteScalar() предназначен для операторов вставки / обновления / удаления и возвращает количество затронутых строк.

В-третьих, но не менее важно: рассмотрите возможность перемещения кода, связанного с базой данных, в класс Repository, а затем вызовите васкод класса репозитория из логики формы.Таким образом, у вас будет многократно используемый код.Простой пример начальной точки для класса репозитория:

public class Repository
{
    public string ConnectionString { get; private set; }

    public Repository(string connectionString)
    {
        this.ConnectionString = connectionString;
    }

    public string GetSchoolNameById(int id)
    {
        string schoolName = null;
        MySqlConnection conn = null;
        try
        {
            conn = new MySqlConnection(this.ConnectionString);
            conn.Open();
            using (MySqlCommand cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT School_Name FROM schools WHERE School_ID=@id";
                cmd.Parameters.AddWithValue("@id", id);
                using (var rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        if (!rdr.IsDBNull(rdr.GetOrdinal("School_Name")))
                        {
                            schoolName = rdr.GetString(rdr.GetOrdinal("School_Name"));
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // maybe log exception here, or rethrow it if you want
            // the consumer to manage it. This depends on how you plan to build your software architecture.
        }
        finally
        {
            // this code will run always, either if everything ran correctly or if some exception occurred in the try block.
            if (conn != null)
            {
                conn.Close();
                conn.Dispose();
            }
        }
        return schoolName;
    }

}

Тогда ваш код формы может быть таким простым:

    Repository rep = new Repository("server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8");
    try
    {
        // the try/catch is necessary if you have decided to re-throw the exception in the Repository.GetSchoolNameById method
        label1.Text = rep.GetSchoolNameById(1);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...