我正在为一个叫做OTServer的游戏服务器编程一个数据库管理器,第二次使用executereader()时遇到了问题。代码如下:

    private void button1_Click(object sender, EventArgs e)
    {
        Form1 f = new Form1();
        MySqlConnection conn = new MySqlConnection();
        conn.ConnectionString = "Server=" + f.GetText1().Text + ";Username=" + f.GetText2().Text + ";Pwd=" + f.GetText3().Text + ";Database=" + f.GetText4().Text + ";";
        conn.Open();
        MySqlCommand cmd = new MySqlCommand("SELECT * FROM `players` WHERE name = @Name", conn);
        cmd.Parameters.AddWithValue("@Name", textBox1.Text);

        MySqlDataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
        while (Reader.Read())
        {
            label7.Text = (string)Reader[1];
            label7.Show();
            label8.Text = Reader[5].ToString();
            label8.Show();
            if ((int)Reader[6] == 1)
            {
                label9.Text = "Sorcerer (1)";
            }
            if ((int)Reader[6] == 2)
            {
                label9.Text = "Druid (2)";
            }
            if ((int)Reader[6] == 3)
            {
                label9.Text = "Paladin (3)";
            }
            if ((int)Reader[6] == 4)
            {
                label9.Text = "Knight (4)";
            }

            if ((int)Reader[6] == 0)
            {
                label9.Text = "None (0)";
            }
            label9.Show();

            if ((int)Reader[3] == 1)
            {
                label10.Text = "Player";
            }

            if ((int)Reader[3] == 2)
            {
                label10.Text = "Tutor";
            }

            if ((int)Reader[3] == 3)
            {
                label10.Text = "Senior Tutor";
            }

            if ((int)Reader[3] == 4)
            {
                label10.Text = "Gamemaster";
            }

            if ((int)Reader[3] == 5)
            {
                label10.Text = "Community Manager";
            }

            if ((int)Reader[3] == 6)
            {
                label10.Text = "God";
            }

            if ((int)Reader[3] < 1 || (int)Reader[3] > 6)
            {
                label10.Text = "Unknown";
            }

            label10.Show();

            label13.Text = "Account: " + Reader[4].ToString();
            label13.Show();
        }
        Reader.Close();

        cmd = new MySqlCommand("SELECT * FROM accounts WHERE id = @Account_ID", conn);
        cmd.Parameters.AddWithValue("@Account_ID", label13.Text);
        Reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

        while (Reader.Read())
        {
            label11.Text = (string)Reader[0];
            label11.Show();
        }
        Reader.Close();
    }

最佳答案

建议的解决方案:尝试在using周围放置一个DataReader块,或在上面调用Dispose

using (DataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
    // ...do something with your data reader... then finish by:
    Reader.Close();
}  // <-- Reader.Dispose() called automatically at the end of using block.

// ...prepare second command...

// the same again for the second command:
using (DataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
    // ...
    Reader.Close();
}

问题的假定原因:DB connection对象可能会执行一些内部记帐以跟踪数据读取器。我发现在类似的情况下,一次只允许一个DataReader。所以我认为你的代码的问题是,当你在执行第二个数据读取器时,你没有显式地将它写下来,所以连接对象认为第一个数据读取器仍然在使用。
另外。。。为什么不简化此代码:
        if ((int)Reader[6] == 1)
        {
            label9.Text = "Sorcerer (1)";
        }
        if ((int)Reader[6] == 2)
        {
            label9.Text = "Druid (2)";
        }
        ...

对于Close语句?:
        int x = (int)(Reader[6]);
        string label9Text = string.Empty;

        switch (x)
        {
            case 1:  label9Text = "Sorcerer (1)";  break;
            case 2:  label9Text = "Druid (2)";     break;
            ...
        }

        label9.Text = label9Text;

(这样你就省去了很多重复的打字。)

10-05 20:32
查看更多