使用select查询时在mscorlib.dll中引发异常:“system.collections.generic.keynotfoundexception”

44u64gxh  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(857)
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);
}

上面的代码返回抛出的异常:mscorlib.dll中的“system.collections.generic.keynotfoundexception”
但是,每当我使用诸如insert、update和delete之类的查询时,它都可以正常工作。就像下面的代码:

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

所以基本上我的问题是:
如果在xamarin.forms(在android中测试)中使用,那么第一块代码就可以正常工作。我可以从数据库中选择。
如果在windows窗体应用程序中使用,则第一个代码块不起作用,并返回所述异常。xamarin.forms和windows窗体应用程序都运行在c上,所以我不知道为什么会发生这种情况。
第二段代码在xamarin.forms和windows窗体应用程序中都可以正常工作。
基本上,我可以运行任何sql查询,但不能选择。

u5rb5r59

u5rb5r591#

首先,如果发生异常,您的代码可以保持连接打开。这个 conn.Close() 应该移到一个 finally 阻止。其次,要查询值,应该使用 cmd.ExecuteReader() 方法,该方法将返回 MySqlDataReader 对象;要处理它,可以使用 using() 构造。这个 ExecuteScalar() 方法用于insert/update/delete语句,并返回受影响的行数。
第三,但同样重要:考虑将与数据库相关的代码移动到存储库类,然后从表单逻辑调用存储库类代码。这样您将拥有一段可重用的代码。存储库类的起点的简单示例:

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

相关问题