Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用SELECT查询时在mscorlib.dll中引发异常:“System.Collections.Generic.KeyNotFoundException”_C#_Mysql_Sql_Winforms_Xamarin.forms - Fatal编程技术网

C# 使用SELECT查询时在mscorlib.dll中引发异常:“System.Collections.Generic.KeyNotFoundException”

C# 使用SELECT查询时在mscorlib.dll中引发异常:“System.Collections.Generic.KeyNotFoundException”,c#,mysql,sql,winforms,xamarin.forms,C#,Mysql,Sql,Winforms,Xamarin.forms,上面的代码返回在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

上面的代码返回在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("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);
}
所以基本上我的问题是:

如果在Xamarin.Forms中使用,那么第一块代码就可以正常工作。表单在Android中测试。我可以从数据库中选择。 如果在Windows窗体应用程序中使用,则第一块代码不起作用,并返回所述异常。Xamarin.Forms和WindowsForms应用程序都在C上运行,所以我不知道为什么会发生这种情况。 第二段代码在Xamarin.Forms和WindowsForms应用程序中都可以正常工作。 基本上,我可以运行任何SQL查询,但不能选择。
首先,如果发生异常,代码可以保持连接打开。控制室应该移到最后一个街区。 其次,要查询值,应该使用cmd.ExecuteReader方法,该方法将返回一个MySqlDataReader对象;要处置它,可以使用using构造。ExecuteScalar方法用于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);
}
然后,您的表单代码可以简单到:

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

}

做指令准备;声明查询后立即使用命令帮助?我还看到一些关于在AddWithValue调用中省略@符号的引用。您检查过实际查询是否返回任何值吗?您还可以告诉我们代码显示错误的确切位置吗?因为引发的异常System.Collections.Generic.KeyNotFoundException是相关的集合异常发生在哪里?我到底是哪一行?MySqlConnection不也是一次性的吗?所以也需要使用构造?我省略了MySqlConnection处理,因为1我忘记了,2我想专注于具体的问题。处理连接是一个很好的主意,应该这样做。但我认为在这里最重要的事情是关闭连接。通常,如果其余代码编写正确,垃圾收集器将优雅地管理处理连接的任务。这不是唯一的办法。您可以添加conn.Dispose;在连接关闭后的最后一个街区;。一次性物品应始终得到处置;打电话。在您的代码中它不是,所以您应该添加它或使用Usingconstruct。是的,这与OP的问题无关,但既然你在回答中提到了使用,我认为你应该是一致的。我现在给你+1更好
    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);
    }