2010-11-21 4 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

어떤 종류의? 어쨌든 명령을 처리하려고 시도하십시오. –

답변

2

권장 해결책 : 다음 코드는 당신의 DataReader 주위에 using 블록을 넣어 시도하거나 그것에 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를 연결 개체 수도 내부 독자를 추적하여 데이터 독자를 추적하십시오. 비슷한 시나리오에서 한번에 DataReader을 허용한다는 것을 알았습니다. 그래서 당신의 코드 문제는 CloseReader, 명시 적으로 Dispose이 아니기 때문에, 두 번째 코드를 실행할 때 첫 번째 데이터 판독기가 여전히 사용 중이라고 연결 개체가 판단 할 것이라고 생각합니다. 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; 

(즉, 당신에게 반복적 인 입력의 꽤 절약 할 수에

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

:


게다가 ... 왜이 코드를 단순화하지 .)

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 등을 사용하도록 제안합니다. 표와 열거 형 비교 –

관련 문제