none
WPF Project, SQL Probleme RRS feed

  • Frage

  • Hallo liebes Forum :)

    Ich mache zur Zeit meine ersten Gehversuche mit C# und habe in VS2010 ein WPF Projekt begonnen und stecke nun leider schon nach kurzer Zeit ziemlich fest.

    Vielleicht kann mir Neuling ja ein Profi hier helfen :)

    Mein Problem liegt darin, daß ich mit meiner SQL bzw sql-Reader implementierung zwar Tabellen auf meinem SQL-Server erstellen und befüllen kann, aber nicht auslesen.
    Ich bekomme immer den Fehler daß im Reader aktuell kein query vorhanden wäre, oder aber versucht würde zu lesen obwohl der reader bereits geclosed wäre.


    Meine Connection-Klasse
    [csharp]class Connection
        {
           

            public MySqlConnection Connect (string host, string user, string password, string database)
            {        
                MySqlConnection conn = new MySqlConnection(); 
              //  this.con.ConnectionString = "server="+host+";database="+database+";UID="+user+";PASSWORD="+password+";";
                conn.ConnectionString = "server=localhost;database=hs;UID=root;PASSWORD=&dannkhs1!;";
                return conn;
            }[/csharp]


    Meine SQL-Handling-Klasse:
    [csharp]

      class Anfragen
        {

    ................
    ................
    ................
    // Insert und reate funktionieren, daher erspare ich sie euch ;)



            public MySqlDataReader select(string com, MySqlConnection c1)
            {
                MySqlConnection con = c1;
                try
                {
                    MySqlCommand command = con.CreateCommand();
                    command.CommandText = com;
                    con.Open();
                    MySqlDataReader reader = command.ExecuteReader();
                    return reader;
                }
                catch (Exception e)
                {
                    // Anweisungen
                    MySqlDataReader reader = null;
                    MessageBox.Show("funzt nicht :(");
                    return reader;
                }
            }

        }


    }[/csharp]


    Und mein Aufruf für die SQL-Befehle

    [csharp] private void button4_Click(object sender, RoutedEventArgs e)
            {
             
                userMain = textBox1.Text;
                passwordMain = passwordBox1.Password;
                Connection con = new Connection();
                Anfragen anf = new Anfragen();
                MySqlConnection sqlCon = con.Connect(ip, user, password, database);
                cmd = "CREATE  TABLE IF NOT EXISTS  `hs`.`new` (  `idnew` INT NOT NULL ,  PRIMARY KEY (`idnew`) );";
                anf.Create(cmd, sqlCon);

                cmd =   "INSERT INTO `hs`.`new` (`idnew`) VALUES (1);" +

                        "INSERT INTO `hs`.`new` (`idnew`) VALUES (2);" +

                        "INSERT INTO `hs`.`new` (`idnew`) VALUES (3);" +

                        "INSERT INTO `hs`.`new` (`idnew`) VALUES (4);";

                anf.insert(cmd, sqlCon);

                cmd = "SELECT * FROM new;";

                MySqlDataReader reader = anf.select(cmd, sqlCon);

                while (reader.Read())
                {
                    MessageBox.Show(reader[2].ToString());

                }
                sqlCon.Close();
            }      [/csharp]


    Ich war mir nicht ganz sicher ob der Beitrag ins SQl oder ins WPF Forum gehört. Falls ich mich falsch entschieden habe verschiebt ihn bitte ins korrekte Unterforum, merci :)

    mfg,
    Phrix
    Donnerstag, 19. Mai 2011 23:05

Antworten

  • Hi Phrix,

    Schau mal ob Dir dieser Code weiterhilft. Die Verbindung wird immer so kurz wie möglich gehalten. Und der Reader wird hier gleich nach der Verwendung freigegeben (d.h. keine Referenz verläßt den lokalen Gültigkeitsbereich):

    using System;
    using MySql.Data.MySqlClient;
    
    namespace MySqlTest {
     class Program {
     static void Main(string[] args) {
      string userMain = GetUserInput("Username: ");
      string passwordMain = GetUserInput("Password: ");
    
      MySqlConnectionStringBuilder connectionBuilder = new MySqlConnectionStringBuilder { 
      Server = "127.0.0.1", 
      Database = "hs", 
      UserID = userMain, 
      Password = passwordMain 
      };
    
      using (MySqlConnection connection = new MySqlConnection(connectionBuilder.ConnectionString)) {
      using (MySqlDataAdapter adapter = new MySqlDataAdapter(@"SELECT * FROM `hs`.`new`;", connection)) {
       using (MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(adapter)) {
       using (MySqlCommand createCommand = new MySqlCommand()) {
        createCommand.CommandText = "CREATE TABLE IF NOT EXISTS `hs`.`new` (`idnew` INT NOT NULL , PRIMARY KEY (`idnew`));";
        createCommand.Connection = connection;
        CreateNewTableIfNotExists(connection, createCommand);
        using (MySqlCommand selectCommand = adapter.SelectCommand) {
        using (MySqlCommand insertCommand = commandBuilder.GetInsertCommand()) {
         using (MySqlCommand deleteCommand = commandBuilder.GetDeleteCommand()) {
         DeleteTestRows(connection, deleteCommand);
         }
         InsertTestRows(connection, insertCommand);
        }
        SelectAllRows(connection, selectCommand);
        }
       }
       }
      }
      }
    
      Console.ReadKey(true);
     }
    
     private static void CreateNewTableIfNotExists(MySqlConnection connection, MySqlCommand createCommand) {
      connection.Open();
      createCommand.ExecuteNonQuery();
      connection.Close();
     }
    
     private static void SelectAllRows(MySqlConnection connection, MySqlCommand selectCommand) {
      connection.Open();
      Console.WriteLine();
      using (MySqlDataReader reader = selectCommand.ExecuteReader()) {
      while (reader.Read())
       Console.WriteLine(reader.GetInt32(0));
      }
      connection.Close();
     }
    
     private static void InsertTestRows(MySqlConnection connection, MySqlCommand insertCommand) {
      connection.Open();
      for (int i = 1; i < 5; i++) {
      insertCommand.Parameters["@p1"].Value = i;
      insertCommand.ExecuteNonQuery();
      }
      connection.Close();
     }
    
     private static void DeleteTestRows(MySqlConnection connection, MySqlCommand deleteCommand) {
      connection.Open();
      for (int i = 1; i < 5; i++) {
      deleteCommand.Parameters["@p1"].Value = i;
      deleteCommand.ExecuteNonQuery();
      }
      connection.Close();
     }
    
     static string GetUserInput(string prompt) {
      Console.Write(prompt);
      return Console.ReadLine();
     }
     }
    }
    

    Der von Dir genannte Fehler tritt oft auf, wenn die zugrundeliegende Connection während Reader.Read() geschlossen wird.

    Sieh Dir bitte auch folgenden Thread an (Elmar Boyes und meine eigenen Beiträge):
    http://social.msdn.microsoft.com/Forums/de-DE/sqlserverde/thread/341a6ff3-653e-405a-b781-8b8589ff4eca/


    Gruß
    Marcel


    Freitag, 20. Mai 2011 18:04
    Moderator

Alle Antworten

  • Hallo Phrix,

    So kann es schon mal nicht funktionieren: Wie man aus dem CREATE TABLE-Statement erfahren kann, hast Du in der Tabelle hs.new eine einzige Spalte (idnew). Beim Iterieren über die Reader-Ergebnisse greifst Du mit reader[2] also auf eine nicht vorhandene Spalte zu. Abgesehen davon, läßt Deine select-Methode vermuten, dass Du nicht ganz sorgfältig mit Deiner Connection umgehst (in der select-Methode, z.B. öffnest Du eine Verbindung, schließt sie aber nicht). Du solltest Dich daran gewöhnen, eine Verbindung zu öffnen, das Command-Objekt auszuführen und unmittelbar darauf die Verbindung wieder zu schließen. Das ersparrt viel Kopfzerbrechen. Es entspricht auch nicht den best practices die Reader-Instanz über Scopes hinweg zu benutzen (eher innerhalb eines einzigen using-Block verwenden). Weitere Probleme könnten durch die Benutzung von Feldern (Variable auf Klassenebene) entstehen. Läßt sich hier nicht genau sagen, da Du den Code nur zum Teil präsentiert hast und zudem dafür eigens umgeschrieben hast (s. Kommentar in connect-Methode aus dem hervorgeht, dass Du ein MySqlConnection-Feld auf Klassenebene verwendest).

    Gruß
    Marcel



    Freitag, 20. Mai 2011 08:48
    Moderator
  • hallo Marcel, danke für deine Antwort.

     

    Die SQL-Conn hatte ich vorher schon in der Select methode direkt wieder geschlossen, da hat er aber rumgemeckert von wegen reader wäre closed, weshalb ich einfach mal probiert hatte die con später zu schließen.

    Den fehler habe ich jetzt weiterhin, auch mit reader[0] bzw reader[1]. : reader closed :(

    Woran könnte es liegen?

     

    Und wenn du sagst man benutzt reader normalerweise nicht über scopes hinweg, was genau meinst du dann? Bzw wie könnte ich das ordentlich lösen? Ich finde einfach kein Beispiel zu meinem Problem :/

     

    mfg,

    Phrix

    Freitag, 20. Mai 2011 11:15
  • Hi Phrix,

    Schau mal ob Dir dieser Code weiterhilft. Die Verbindung wird immer so kurz wie möglich gehalten. Und der Reader wird hier gleich nach der Verwendung freigegeben (d.h. keine Referenz verläßt den lokalen Gültigkeitsbereich):

    using System;
    using MySql.Data.MySqlClient;
    
    namespace MySqlTest {
     class Program {
     static void Main(string[] args) {
      string userMain = GetUserInput("Username: ");
      string passwordMain = GetUserInput("Password: ");
    
      MySqlConnectionStringBuilder connectionBuilder = new MySqlConnectionStringBuilder { 
      Server = "127.0.0.1", 
      Database = "hs", 
      UserID = userMain, 
      Password = passwordMain 
      };
    
      using (MySqlConnection connection = new MySqlConnection(connectionBuilder.ConnectionString)) {
      using (MySqlDataAdapter adapter = new MySqlDataAdapter(@"SELECT * FROM `hs`.`new`;", connection)) {
       using (MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(adapter)) {
       using (MySqlCommand createCommand = new MySqlCommand()) {
        createCommand.CommandText = "CREATE TABLE IF NOT EXISTS `hs`.`new` (`idnew` INT NOT NULL , PRIMARY KEY (`idnew`));";
        createCommand.Connection = connection;
        CreateNewTableIfNotExists(connection, createCommand);
        using (MySqlCommand selectCommand = adapter.SelectCommand) {
        using (MySqlCommand insertCommand = commandBuilder.GetInsertCommand()) {
         using (MySqlCommand deleteCommand = commandBuilder.GetDeleteCommand()) {
         DeleteTestRows(connection, deleteCommand);
         }
         InsertTestRows(connection, insertCommand);
        }
        SelectAllRows(connection, selectCommand);
        }
       }
       }
      }
      }
    
      Console.ReadKey(true);
     }
    
     private static void CreateNewTableIfNotExists(MySqlConnection connection, MySqlCommand createCommand) {
      connection.Open();
      createCommand.ExecuteNonQuery();
      connection.Close();
     }
    
     private static void SelectAllRows(MySqlConnection connection, MySqlCommand selectCommand) {
      connection.Open();
      Console.WriteLine();
      using (MySqlDataReader reader = selectCommand.ExecuteReader()) {
      while (reader.Read())
       Console.WriteLine(reader.GetInt32(0));
      }
      connection.Close();
     }
    
     private static void InsertTestRows(MySqlConnection connection, MySqlCommand insertCommand) {
      connection.Open();
      for (int i = 1; i < 5; i++) {
      insertCommand.Parameters["@p1"].Value = i;
      insertCommand.ExecuteNonQuery();
      }
      connection.Close();
     }
    
     private static void DeleteTestRows(MySqlConnection connection, MySqlCommand deleteCommand) {
      connection.Open();
      for (int i = 1; i < 5; i++) {
      deleteCommand.Parameters["@p1"].Value = i;
      deleteCommand.ExecuteNonQuery();
      }
      connection.Close();
     }
    
     static string GetUserInput(string prompt) {
      Console.Write(prompt);
      return Console.ReadLine();
     }
     }
    }
    

    Der von Dir genannte Fehler tritt oft auf, wenn die zugrundeliegende Connection während Reader.Read() geschlossen wird.

    Sieh Dir bitte auch folgenden Thread an (Elmar Boyes und meine eigenen Beiträge):
    http://social.msdn.microsoft.com/Forums/de-DE/sqlserverde/thread/341a6ff3-653e-405a-b781-8b8589ff4eca/


    Gruß
    Marcel


    Freitag, 20. Mai 2011 18:04
    Moderator
  • Vielen Dank für die Hilfe, jetzt funktioniert alles :)
    Donnerstag, 26. Mai 2011 23:00