Laden...

MySQL DataReader

Erstellt von Kalle vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.807 Views
K
Kalle Themenstarter:in
31 Beiträge seit 2007
vor 15 Jahren
MySQL DataReader

verwendetes Datenbanksystem: MySQL

Hallo liebe comm,

Ich habe ein Tool geschrieben das Daten von meinen MySQL Server verwendet und diese bearbeitet.

Ich benutze kleine Funktionen wie diese:

    public static int GetInformation(string str1)
    {
        MySqlCommand cmd = new MySqlCommand("SELECT column1 FROM database WHERE column2 = '" + str1 + "'", sql);
        MySqlDataReader reader = null;
        reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            reader.Close();
            return reader.GetInt16(0);
        }
        reader.Close();
        return 0;
    }

So nun ist es aber so wenn mehrere dieser Funktionen die den MySqlDataReader verwenden zugleich aufgerufen werden kommt folgendes Exception:

There is already an open DataReader associated with this Connection which must be closed first.

Da ich MySQL benutze und nicht den Windows SQL Server kann ich in meinen Connection String nicht MultipleActiveResultSets=True einfügen um das Problem zu beheben.

Könnt ihr mir sagen wie ich den Fehler beheben kann?

mfg Kalle

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo Kalle,

Könnt ihr mir sagen wie ich den Fehler beheben kann?

Um diesen Fehler zu beheben musst du wahrscheinlich dein Konzept ein wenig überdenken.
Du kannst entweder für jeden DataReader eine neue Verbindung öffnen (sofern das nicht zu viele sind).
Oder du stellst irgendwie sicher, dass immer ein DataReader nach dem anderen behandelt wird.

kann ich in meinen Connection String nicht MultipleActiveResultSets=True einfügen

Ich kenne mich mit mySQL nicht aus, aber vielleicht gibts da ja auch etwas, was die selbe Funktionalität bietet.

mfg
michael

K
Kalle Themenstarter:in
31 Beiträge seit 2007
vor 15 Jahren

Ich würde auch auch Windows sql server umsteigen habs auch installiert aber weiß absolut nicht was ich machen soll.
Hab sql 2005 express irgendjemand eine Ahnung?

343 Beiträge seit 2007
vor 15 Jahren

Hallo,

Die Express Edition vom SQL 2005 Server ist recht gut, kann ich nur empfehlen.

Um dein Problem mit mySQL zu lösen fallen mir spontan drei Lösungsmöglichkeiten ein:

1.) Du benutzt eine DataTable und lädts dir alle Daten dieser "Information-Tabelle" in dieses Dataset (zum Beispiel beim Programmstart).
Nachteile: braucht mehr Speicher, Daten sind nicht immer aktuell
Vorteil: Zugriff auf einzelne Informationen geht schneller

2.) Baue jedesmal in GetInformation eine neue Verbindung zur Datenbank auf.
IST NICHT zu empfehlen, da dies recht ineffizient wäre. Würd ich nur machen, wenn die Funktion nicht so schnell sein muss und du dein Konzept so wenig wie möglich ändern willst

3.) Mit Monitor.Enter und Monitor.Exit (oder einer anderen dir beliebigen Methode) diesen Codeabschnitt so umprogrammieren, dass er immer nur einmal gleichzeitg ausgeführt werden kann.

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
J
3.331 Beiträge seit 2006
vor 15 Jahren

2.) Baue jedesmal in GetInformation eine neue Verbindung zur Datenbank auf.
IST NICHT zu empfehlen, da dies recht ineffizient wäre. Würd ich nur machen, wenn die Funktion nicht so schnell sein muss und du dein Konzept so wenig wie möglich ändern willst

Im Gegenteil, das ist die empfohlene Vorgehensweise!

Das gesamte Konzept von ADO.NET baut darauf auf, dass eine DbConnection nur kurzfristig geöffnet wird, wenn sie benötigt wird, und nach Gebrauch wieder geschlossen wird. (Gleiches gilt deshalb auch für DbDataReader und in der Regel für DbDataAdapter, weil diese nur während der DbConnection benutzt werden.) Für wiederholten Gebrauch werden die Verbindungen in einem ConnectionPool verwaltet, sodass dieselbe Verbindung bei einem neuen Aufruf schnell wieder bereit steht.

Für nähere Informationen siehe :rtfm: Verbindungspooling [ADO.NET].

Das übliche Verfahren sieht deshalb etwa so aus:

using(DbConnection conn = new DbConnection(connString)) {
   conn.Open();
   DbCommand cmd = new DbCommand(cmdString, conn);
   cmd.Parameters.AddWithValue("@ID", id);
   DbDataReader reader = cmd.ExecuteReader();
   while(reader.Read()) {
       value = reader.GetInt32(0);
   }
   reader.Close();
}

Je nach DbProvider müssen die einzelnen Schritte evtl. anders verbunden werden, und es werden andere Überladungen benötigt; aber im Prinzip geht es so.

Jürgen

PS. Gewöhne es Dir schnell ab, einen CommandText per String-Verknüpfung zu erstellen; das benötigt oft fehleranfällige Konvertierungen und ermöglicht Sql-Injection. Benutze stattdessen unbedingt, wie von mir skizziert, DbParameter.

A
154 Beiträge seit 2005
vor 15 Jahren

Hallo Kalle,

ich kann dich beruhigen, beim MSSql hättest du das selbe Problem 😁

Wie schon geschrieben, entweder du versucht die Zugriffe zu synchronisieren oder man baut wirklich ständig neue Verbindungen auf.

Das Synchronisieren bremst aber vermutlich die ganze Anwendung nur aus. Das mit Monitor.Enter / Exit würde auch nicht funktionieren, da es immer etwas dauert bis die Verbindung wirklich wieder bereitsteht.

Stand lange Zeit vor dem selben Problem 🙁

.