2017-09-08 2 views
0

Ich habe eine Klasse und meine MySqlConnection gibt es in:Verbindung schließen/MySqlDataReader funktioniert nicht

public class DB 
{ 
    private static MySqlConnection _Connection; 
    public static MySqlConnection Connection 
    { 
     get 
     { 
      if(_Connection == null) 
      { 
       string cs = string.Format("SERVER={0}; DATABASE={1}; UID={2}; PWD={3};", SERVER_ADRESS, DATABASE, UID, PWD); 
       _Connection = new MySqlConnection(cs); 
      } 

      if(_Connection.State == System.Data.ConnectionState.Closed) 
       try 
       { 
        MessageBox.Show("MySQL Connection ist geschlossen. Öffne Sie"); 
        _Connection.Open(); 
       } 
       catch(MySqlException ex) 
       { 
        switch (ex.Number) 
        { 
         case 0: 
          MessageBox.Show("Verbindung zum Server konnte nicht hergestellt werden."); 
          break; 
         case 1045: 
          MessageBox.Show("Ungültiger Benutzername/Passwort."); 
          break; 
         default: 
          MessageBox.Show(ex.Message); 
          break; 
        } 
       } 
      return _Connection; 
     } 
    } 
} 

So kann ich diese Verbindung verwenden in allen anderen Klassen mit DB.Connection.

Aber jetzt bekomme ich "DataReader ist bereits offen". Aber alle meine DataReader sind in Verwendung.

Wir beginnen bei meiner Login-Seite:

using (loginreader = cmd.ExecuteReader()) 
      { 
       if (loginreader.Read()) 
       { 
        DB.Connection.Close(); 
        return true; 
       } 
       else 
       { 
        DB.Connection.Close(); 
        return false; 
       } 
       loginreader.Close(); 
      } 

Ich denke, das funktioniert nicht. Aber die erste Fehlermeldung nach der Anmeldung bekomme ich auf eine andere Klasse in Zeile 83:

DataTable schema = null; 

      using (var schemaCommand = new MySqlCommand("SELECT * FROM " + firmCustomerTablename, connection)) 
      { 
       using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly)) 
       { 
        schema = reader.GetSchemaTable(); 
       } 
      } 

die in einer Verwendung ist auch. Also ich verstehe nicht warum ich diesen Fehler bekomme. Ich denke, das Schließen der Verbindungen/die DataReader funktionieren nicht.

Vor dieser Änderung hatte ich eine Verbindung für jede Website. Aber mein Programm hatte keine gute Leistung. Also habe ich beschlossen, 1 Verbindung zu machen, die immer offen ist und nur Queries zu dieser offenen Verbindung aufruft. Und jetzt bekomme ich DataReader-Fehler.

Kann mir jemand erklären, warum der DataReader nicht benutzt wird? Und Zeile 83 ist kein DataReader, es ist ein Var, also weiß ich nicht, warum ich diesen Fehler bei dieser Zeile bekomme.

+3

eine statische Verbindung für die ganze Instanz zu haben, ist keine gute Lösung. Sie sollten Verbindungen für jede Abfrage oder Aktualisierung öffnen, die Sie ausführen. Wenn Sie so vorgehen, führt das zu vielen weiteren Problemen, die über das hinausgehen, was Sie beschreiben. Wenn das eine schlechte Leistung verursacht, dann löse dieses Problem (stelle sicher, dass die Verbindungen richtig zusammengefasst sind, dass du sie rechtzeitig entsorgst/schließt, etc.) –

+0

Es tötet die Leistung, um die Verbindung alle 5 Sekunden zu öffnen. Weil alle Dinge aus der Datenbank gelesen werden. Ein Klick auf den Button öffnet ein Fenster mit Datenbankinhalt. Ein weiterer Klick auf eine andere Schaltfläche etc. –

+2

Es sollte nicht die Leistung töten, um Verbindungen alle 5 Sekunden zu erstellen. Wenn dies der Fall ist, ist etwas nicht richtig eingerichtet. Haben Sie tatsächlich bestätigt, dass es passiert oder nur angenommen? Siehe: https://stackoverflow.com/questions/9705637/execute- reader-requires-an-open-and-available-connection-the-connections-curren/9707060#9707060 und https://stackoverflow.com/questions/26089420/ c-sharp-mysql-connection-pooling –

Antwort

1

Es klingt wie Ihre Probleme in Bezug auf Verbindungsstatusverwaltung sind? Ich verstehe vielleicht nicht ganz, was Sie fragen, aber durch das Design using Anweisungen im Zusammenhang mit Verbindungen wird die Verbindung geschlossen. Sie sind syntaktischer Zucker für try {} catch {} finally. Viel zu oft sehe ich Beispiele für Connection-Objekte, Command-Objekte usw., die nicht IDisposable verwenden und nicht richtig angeordnet/geschlossen sind.

In diesem Code sehe ich nicht, dass eine Verbindung erneut geöffnet wird, damit der Befehl ausgeführt werden kann.

DataTable schema = null; 

     using (var schemaCommand = new MySqlCommand("SELECT * FROM " + firmCustomerTablename, connection)) 
     { 
      using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly)) 
      { 
       schema = reader.GetSchemaTable(); 
      } 
     } 

Hier ist eine Grundidee:

 using (var conn = new SqlConnection(connectionString: "")) 
     { 
      conn.Open(); 

      using (var cmd = new SqlCommand(cmdText: "cmdText", connection: conn)) 
      { 
       using (var reader = cmd.ExecuteReader()) 
       { 
        while (reader.Read()) 
        { 
         // 
        } 
       } 
      } 

     } 

Dokumentation: MSDN SqlConnection Class

+0

ich würde vorschlagen zu zeigen, wie man die Verbindungen sicher auch als das war sein erstes Problem. Sie können beginnen, indem Sie 'cmd.ExecuteReader (CommandBehavior.CloseConnection)' hinzufügen. Dies schließt automatisch den Leser, der die Leseschleife beendet hat. Daher müssen Sie den Leserstatus nicht überprüfen. Sie können einfach die Nullfunktionalität verwenden und anschließend die Verbindung schließen. – thanatorr

+0

Ich weiß, dass Ihre Verwendung Aussagen nigate dies, aber ID sagen, es lohnt sich, ein Verständnis von was passiert zuerst? bevor Sie in Syntaxzucker eintauchen. – thanatorr

+0

@thanatorr, danke für dein Feedback. Immer lernen. –

Verwandte Themen