2011-12-01 2 views
4

이전 코드를 변경하여 '사용'을 사용하지 않습니다. 더 일찍 작동하고 다른 클래스의 코드는 기본적으로 같은 것을 나타내지 만 작동합니다.이전 DataReader를 닫지 않았지만 어디에서?

나는 2 시간 동안 그것을 쳐다 보았다. 그리고 나는 단지 문제가 어디에 있는지 알 수 없다. 오류 : There is already an open DataReader associated with this command which must be closed first.

// May be public so we can display 
// content of file from different forms. 
public void DisplayFileContent(string filePath) 
{ 
    // Counting all entries. 
    int countEntries = 0; 

    // Encrypting/Decrypting data. 
    EncryptDecrypt security = new EncryptDecrypt(); 

    using (OleDbConnection connection = new OleDbConnection()) 
    { 
     connection.ConnectionString = 
      "Provider=Microsoft.ACE.OLEDB.12.0;" + 
      "Data Source=" + filePath + ";" + 
      "Persist Security Info=False;" + 
      "Jet OLEDB:Database Password=" + 
      hashPhrase.ShortHash(storedAuth.Password) + ";"; 

     using (OleDbCommand command = new OleDbCommand 
      ("Select * FROM PersonalData", connection)) 
     { 
      OleDbDataReader read; 

      try 
      { 
       // Open database connection. 
       connection.Open(); 

       // Create a data reader. 
       read = command.ExecuteReader(); 

       // Clearing the textbox before proceeding. 
       txtDisplay.Text = string.Empty; 

       // Checking if there is any data in the file. 
       if (read.HasRows) 
       { 
        // Reading information from the file. 
        while (read.Read()) 
        { 
         // Count all entries read from the reader. 
         countEntries++; 

         // Reading all values from the file as string. 
         // While each string is encrypted, we must decrypt them. 
         // User name and password is the same as user provided 
         // while authentication. 
         txtDisplay.Text += "=== Entry ID: " + read.GetValue(0) + 
          " ===" + Environment.NewLine; 
         txtDisplay.Text += "Type: " + security.Decrypt 
          (read.GetString(1), storedAuth.Password, 
          storedAuth.UserName) + Environment.NewLine; 
         if (!read.IsDBNull(2)) 
          txtDisplay.Text += "URL: " + 
           security.Decrypt(read.GetString(2), 
           storedAuth.Password, storedAuth.UserName) + 
           Environment.NewLine; 
         if (!read.IsDBNull(3)) 
          txtDisplay.Text += "Software Name: " + 
           security.Decrypt(read.GetString(3), 
           storedAuth.Password, storedAuth.UserName) + 
           Environment.NewLine; 
         if (!read.IsDBNull(4)) 
          txtDisplay.Text += "Serial Code: " + 
           security.Decrypt(read.GetString(4), 
           storedAuth.Password, storedAuth.UserName) + 
           Environment.NewLine; 
         if (!read.IsDBNull(5)) 
          txtDisplay.Text += "User Name: " + 
           security.Decrypt(read.GetString(5), 
           storedAuth.Password, storedAuth.UserName) + 
           Environment.NewLine; 
         if (!read.IsDBNull(6)) 
          txtDisplay.Text += "Password: " + 
           security.Decrypt(read.GetString(6), 
           storedAuth.Password, storedAuth.UserName) + 
           Environment.NewLine; 
         txtDisplay.Text += Environment.NewLine; 
        } 
       } 
       else 
       { 
        txtDisplay.Text = "There is nothing to display! " + 
         "You must add something before so I can display anything here."; 
       } 

       // Displaying number of entries in the status bar. 
       tsslStatus.Text = "A total of " + countEntries + " entries."; 

       // Selecting 0 character to make sure text 
       // isn't completly selected. 
       txtDisplay.SelectionStart = 0; 

       command.ExecuteNonQuery(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Error: " + ex.Message); 
      } 
     } 
    } 
} 
+1

처음 메서드를 호출 할 때도 발생합니까? – BoltClock

+0

@ BoltClock ♦ : 메소드가 호출 될 때마다 발생합니다. 그러나 나는 그것을 단지 나의 주요한 형태로 2 사용하고있다. – HelpNeeder

+3

왜 마지막에'command.ExecuteNonQuery();'를 호출합니까? – mellamokb

답변

6

이 필요합니다. 먼저 DataReader를 닫아야합니다.

내가 어쨌든 사용하여 블록에서 DataReader를를 사용하는 코드를 포장 권하고 싶습니다 :

으로 위의 지적
using(OleDbDatareader read = command.ExecuteReader()) 
{ 

    ... 

} 

, command.ExecuteNonQuery()는 당신이 수익을 기대하지 않는 명령을 실행하는 것입니다 결과. 이들은 일반적으로 삽입, 업데이트 또는 삭제이지만, 동일한 작업을하는 저장된 proc 호출을 포함하거나 반환 된 결과를 신경 쓰지 않는 경우

+0

좋은 지적! 감사! – HelpNeeder

3

에 필요한

command.ExecuteNonQuery(); 

당신의 라인 전 :

나는 단 하나의 독자하지만 난 오류를 얻고있다 DisplayFileContent 방법을 사용하고 각 시간이

read.Close(); 

또한 연결을 사용하면 자동으로 작동하지 않습니다. 그것을 수학적으로 닫는다. 따라서 연결이 문을 사용하여이 끝나기 전에, 당신은 당신은 단지 catch 블록 전에 command.ExecuteNonQuery를 호출된다

connection.Close(); 
+1

기술적으로 예. 하지만 OP는'SELECT' 문으로'command.ExecuteNonQuery()'를 호출해서는 안됩니다. – mellamokb

+0

코드가 connection using 구문의 닫는 괄호에 도달하면 dispose가 호출됩니다. 폐기 처분으로 연결이 닫힙니다. http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close.aspx "SqlConnection이 범위를 벗어나면 닫히지 않습니다. 따라서 Close 또는 Dispose를 호출하여 명시 적으로 연결을 닫아야합니다 .Exclude와 Dispose는 기능적으로 동일합니다. " – dash

1

데이터 판독기를 닫을 코드가 없습니다. 마지막으로 캐치 부분 후

추가 :

finally { 
     if (read != null) 
     { 
      read.Close(); 
     } 
} 

수정 # 1 : 나는 옆 명령을 실행하기 전에 닫습니다, 그래서 하나 catch 블록 전에 (해당되는 경우) 마지막 줄을 삭제하고 마지막으로 추가해야합니다, 실수를 블록을 사용하거나 변수 읽기를 사용하여 추가하십시오.

+0

글쎄, 내가 '사용'을 사용하고 있기 때문에, 어떤 사람은 그 물건을 닫고 처분 할 것이라고 지적했다. – HelpNeeder

+0

@HelpNeeder, 예, 둘 중 하나를 사용하거나 '사용'을 사용해야합니다. –

+0

@HelpNeeder, 문제가 완전히 해결 된 경우 대시의 답변을 수락하는 것을 고려해보십시오. –

관련 문제