Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
MySQL DataReader
Kalle
myCSharp.de - Member



Dabei seit:
Beiträge: 31

Themenstarter:

MySQL DataReader

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
michlG
myCSharp.de - Experte

Avatar #avatar-2909.png


Dabei seit:
Beiträge: 3.430
Herkunft: Naturns - Südtirol - Italien

beantworten | zitieren | melden

Hallo Kalle,
Zitat von 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.
Zitat
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
private Nachricht | Beiträge des Benutzers
Kalle
myCSharp.de - Member



Dabei seit:
Beiträge: 31

Themenstarter:

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
preli
myCSharp.de - Member

Avatar #avatar-2343.png


Dabei seit:
Beiträge: 343
Herkunft: Österreich

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
juetho
myCSharp.de - Member



Dabei seit:
Beiträge: 3.331
Herkunft: Berlin

beantworten | zitieren | melden

Zitat von preli
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.
private Nachricht | Beiträge des Benutzers
AlfameisterT
myCSharp.de - Member



Dabei seit:
Beiträge: 154

beantworten | zitieren | melden

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

.
private Nachricht | Beiträge des Benutzers