2010-11-21 25 views
1

我正在編寫一個名爲OTServer的遊戲服務器的數據庫管理器,而且我在第二次使用executereader()時遇到了問題。這裏是代碼:是否可以使用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(); 
    } 
+0

什麼樣的問題?無論如何設法也處置命令。 – 2010-11-21 13:53:42

回答

2

建議解決方案:嘗試把一個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(); 
} 

您的問題可能的原因:數據庫連接對象可能做一些內部記錄來跟蹤數據讀者。我發現在一個類似的情況下,你一次只允許一個DataReader。所以我相信你的代碼的問題是,雖然你CloseReader,你沒有明確地Dispose d it,所以連接對象認爲當你執行第二個數據讀取器時,第一個數據讀取器仍然在使用。


除了...爲什麼不簡化這個代碼:

 if ((int)Reader[6] == 1) 
     { 
      label9.Text = "Sorcerer (1)"; 
     } 
     if ((int)Reader[6] == 2) 
     { 
      label9.Text = "Druid (2)"; 
     } 
     ... 

switch聲明?:

 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; 

(這會節省你不少重複輸入的)

1

那麼,假設你的代碼是正確的喲當你在代碼中顯示時,你不應該在執行兩個閱讀器時遇到問題。也許你有問題,因爲不處理命令或其他東西。我推薦一種類似的方法(使用Northwind db製作的示例):

using (SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;")) 
     { 
      connection.Open(); 

      using (SqlCommand command = new SqlCommand("SELECT * FROM Orders", connection)) 
      { 
       using (SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow)) 
       { 
        while (reader.Read()) 
        { 
         Console.WriteLine(reader.GetString(2)); 
        } 
       } 
      } 

      using (SqlCommand command = new SqlCommand("SELECT * FROM Products", connection)) 
      { 
       using (SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow)) 
       { 
        while (reader.Read()) 
        { 
         Console.WriteLine(reader.GetString(1)); 
        } 
       } 
      } 
     } 

您應該在識別播放器類型時清理代碼。創建一個枚舉,而不是:

public enum PlayerType 
{ 
    None = 0, 
    Sorcerer = 1, 
    Druid = 2, 
    Paladin = 3 
} 

然後一邊讀執行以下操作:

PlayerType playerType = (PlayerType)reader.GetInt32(6); 
label9.Text = playerType.ToString(); 
+1

建議使用player_type,player_class等。table vs enum – 2010-11-21 14:35:32