Laden...

Klasse erzeugen, Eigenschaften festlegen, Methoden zum Lesen und Schreiben

Erstellt von sinfoe vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.249 Views
S
sinfoe Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren
Klasse erzeugen, Eigenschaften festlegen, Methoden zum Lesen und Schreiben

Hallo Leute,

nach viel Lesen und Probieren habe ich eine Klasse namens clsKunden funktionsfähig angelegt. Die Eigenschaften habe ich hier auf eine übersichtliche Anzahl begrenzt, bei den Methoden habe ich eine zum Lesen aus einer Tabelle und eine zum Schreiben in eine Tabelle.


  class clsKunden
  {

    // Properties
    public string connStr
    {
      get { return Program.g_globSettings.ConnString; } // = "Data Source=.\\SQLEXPRESS;Initial Catalog=MyDB;Integrated Security=True";
    }

    public string id
    {
      get { return m_customer_id; }
      set { m_customer_id = value; }
    }
    private string m_customer_id = "";

    public string nachname
    {
      get { return m_nachname; }
      set { m_nachname = value; }
    }
    private string m_nachname = "";

    public string vorname
    {
      get { return m_vorname; }
      set { m_vorname = value; }
    }
    private string m_vorname = "";
  
    // end of Properties  



    // clsKunden.Clear
    public void Clear()
    {
      id = "";
      vorname = "";
      nachname = "";
    } // eof clsKunden.Clear

    // clsKunden.Read
    // liest genau eine Datensatz aus der Tabelle "customer"
    public void Read(string customer_id)
    {
      if (customer_id == "") return;
      SqlConnection cn = new SqlConnection(connStr);
      string sqlStr = "SELECT * FROM customer where ID='" + customer_id + "'";
      SqlCommand sqlCmd = new SqlCommand(sqlStr, cn);
      cn.Open();
      SqlDataReader reader = sqlCmd.ExecuteReader();
      try
      {
        if (reader.HasRows)
        {
          reader.Read();

          id = reader["ID"].ToString();
          vorname = reader["tVorname"].ToString();
          nachname = reader["tNachname"].ToString();
        }
      }
      finally
      {
        reader.Close();
        cn.Close();
      }
    } // eof clsKunden.Read


    // clsKunden.Write
    // schreibt den Datensatz in Tabelle 
    // Add, wenn ID neu ist, 
    // Update wenn ID vorhanden ist
    public void Write(string id)
    {
      // ermittle, ob Datensatz mit dieser id vorhanden ist
      SqlConnection cn = new SqlConnection(connStr);
      string sqlStr = "SELECT COUNT(*) AS TOTAL FROM customer where ID='" + id + "'";
      SqlCommand sqlCmd = new SqlCommand(sqlStr, cn);
      if (Convert.ToInt16(sqlCmd.ExecuteScalar().ToString()) == 0) sqlStr = "Add";
      else sqlStr = "Update";

      sqlStr += " customer set tVorname='" + vorname + "', tNachname='" + nachname + "' WHERE ID='" + id + "'";
      SqlCommand cmd = new SqlCommand(sqlStr, cn);
      cmd.Connection.Open();
      cmd.ExecuteNonQuery();
    } // eof clsKunden.Write

  } // eof class clsKunden


Benutzt wird das ganze in einem Formular mit Textbox (edID, edVorname, edName) zum ändern der Werte.


    private void btRdKdDaten3_Click(object sender, EventArgs e)
    {
      aktkd_id = Program.g_globSettings.IDString;  // wird durch Doppelklick in einem DataGridView eines anderen Form gesetzt
      clsKunden aktKd = new clsKunden();    // aktueller Kunde
      aktKd.Clear();
      aktKd.Read(aktkd_id);
      edID.Text = aktKd.id;                     // nur zur Anzeige
      edVorname.Text = aktKd.vorname;
      edName.Text = aktKd.nachname;
    }

    private void btWrKdDaten3_Click(object sender, EventArgs e)
    {
      aktkd_id = Program.g_globSettings.IDString;
      clsKunden aktKd = new clsKunden();
      aktKd.vorname = edVorname.Text;
      aktKd.nachname = edName.Text;
      aktKd.Write(aktkd_id);
    }


Das Ganze ist getestet und funktioniert wie gewünscht.

Der Thread soll zwei Funktionen erfüllen:

  1. anderen Einsteigern ein Code-Beispiel bieten
  2. Hinweise, Anregungen, Verbesserungsvorschläge und andere Wege von denen aufgezeigt bekommen, die mehr praktische Erfahrung bei der Nutzung der Möglichkeiten von VS haben.

Insbesondere stellt sich die Frage, wie man die obige Funktion "write" unter Nutzung von SqlCommand, CommandType.StoredProcedure und SqlParameter zum gewünschten Ergebnis kommt. Aber das ist vielleicht Thema für einen anderen Thread.

mfg

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo sinfoe,

du solltest deine Klasse nach den Namensrichtlinien von Klassen von clsKunden in Kunde umbennen: Die Ungarische Notation wird im Rahmen von .NET nicht verwendet. Weiterhin werden Klassen in der Regel im Singular benannt.
Wo wir gerade beim Thema Namensrichtlinien / formale Aspekte sind: Eigenschaften werden i.d.R. auch groß geschrieben.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

D
496 Beiträge seit 2005
vor 14 Jahren

parameter im sql command wären auch nicht schlecht, wurde schon oft besprochen dass das so kein guter stil ist bzw. sogar ein sicherheitsrisiko darstellen kann.

"Programming is similar to sex. If you make a mistake, you have to support it for the rest of your life."

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo sinfoe,

  1. anderen Einsteigern ein Code-Beispiel bieten

für eine Einsteiger ein gewagtes Unterfangen und, sorry, leider nicht gelungen, da zu viel suboptimal gelöst wurde. Neben dem schon Gesagten, gehört das Lesen und Schreiben aus der und in die Datenbank nicht in die Klasse, sondern in den Data Abstraction Layer.

Und Fragen und Antworten zu SQL gehören - wie du richtig erkannt hast - nicht in diesen Thread.

herbivore

S
sinfoe Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren

Hallo,

entsprechend Euren Hinweisen hier nun die 2. Fassung:

Zuerst die überarbeitete Klasse Kunde (vorher clsKunden) mit korrigierten Benennungen:


  class Kunde
  {

    public string connStr
    {
      get { return Program.g_globSettings.ConnString; }
    }


    public string Id
    {
      get { return id; }
      set { id = value; }
    }
    private string id = "";

    public string NachName
    {
      get { return nachName; }
      set { nachName = value; }
    }
    private string nachName = "";

    public string VorName
    {
      get { return vorName; }
      set { vorName = value; }
    }
    private string vorName = "";

    // end of Properties  

 
    // Kunde.Clear  -  unverändert
    public void Clear()
    {
      id = "";
      vorname = "";
      nachname = "";
    } // eof Kunde.Clear


Die ursprünglich noch vorhandenen Funktionen Read und Write wurden ausgelagert in eine Klasse namens DAL (für Data Abstraction Layer), in der, wenn ich @herbivore richtig verstanden habe, auch alle anderen Prozeduren und Funktionen unterzubringen sind, die auf die Datenbank lesend und schreibend zugreifen:


class DAL
  {
    public string connStr = Program.g_globSettings.ConnString;


    public Kunde ReadRec(string id)
    {
      Kunde res = new Kunde();
      string sql = "select * from customer where id = '" + id.ToString() + "'";
      SqlConnection cn = new SqlConnection(connStr);      //Verbindung herstellen  //using System.Data.SqlClient;
      cn.Open();
      SqlCommand cmd = new SqlCommand(sql, cn);           //Befehl ausführen
      SqlDataAdapter da = new SqlDataAdapter(cmd);        //Datenadapter erzeugen
      DataSet ds = new DataSet();                         //Datenset erzeugen     //using System.Data;
      da.Fill(ds);                                        //Daten aus der Datenbank abholen
      cn.Close();                                         //Datenbankverbindung schließen
      if (ds.Tables.Count > 0)                            //sollte hier immer genau Eins sein
      {
        DataTable dt = ds.Tables[0];                      //Datentabelle einlesen
        DataRow dr = dt.Rows[0];                          //Datensatz einlesen
        {
          res.Id = dr["ID"].ToString();                   //Datensatz an Variable der Klasse Kunde übergeben
          res.VorName = dr["tVorname"].ToString();
          res.NachName = dr["tNachname"].ToString();
        }
      }
      else res.Id = id;                                   //nur ID an Variable übergeben 
      return res;                                         
    }

    public void WriteRec(Kunde rec)
    {
      string sql = "select * from customer where id = '" + rec.Id.ToString() + "'";
      SqlConnection cn = new SqlConnection(connStr);      //Verbindung herstellen  //using System.Data.SqlClient;
      cn.Open();
      SqlCommand cmd = new SqlCommand(sql, cn);           //Befehl ausführen
      SqlDataAdapter da = new SqlDataAdapter(cmd);        //Datenadapter erzeugen
      DataSet ds = new DataSet();                         //Datenset erzeugen     //using System.Data;
      //da.Fill(ds);                                      //Daten aus der Datenbank abholen
      da.Fill(ds, "Adresse");                             //mit Vergabe eines Tabellen-Namen 
      cn.Close();                                         //Datenbankverbindung schließen
      if (ds.Tables.Count > 0)                            //sollte hier immer genau Eins sein
      {
        //DataTable dt = ds.Tables[0];                    //Datentabelle einlesen
        DataTable dt = ds.Tables["Adresse"];              //
        DataRow dr = dt.Rows[0];                          //1. Datensatz einlesen
        {                                                 //nur änderbare Felder in Datensatz übertragn
          //dr["ID"] darf nicht verändert werden (nur bei Neuanlage)
          dr["tVorname"] = rec.VorName;
          dr["tNachname"] = rec.NachName;
        }
        SqlCommandBuilder cb = new SqlCommandBuilder(da); // Befehle für Datenadapter erzeugen
        //da.Update(ds.Tables[0]);                          // schreiben der Änderungen in die Tabelle
        da.Update(ds.Tables["Adresse"]);                    //
      }
    }

Benutzt wird das dann im Form mit den entsprechenden TextBoxen


    private void btRdKdDaten4_Click(object sender, EventArgs e)
    {
      aktkd_id = Program.g_globSettings.IDString;  //aktkd_id aus Doppelclick im DataGridView übernommen
      DAL dba = new DAL();                          // dba steht für Datenbank-Aktion
      Kunde aktKd = new Kunde();
      aktKd = dba.ReadRec(aktkd_id);            //Datensatz lesen  von Datenban in Klasse 
      // Daten von Klasse zum GUI zwecks nachfolgender Bearbeitung
      tbID.Text = aktKd.Id;                     // nur zur Anzeige
      tbVorname.Text = aktKd.VorName;
      tbName.Text = aktKd.NachName;
    }

    private void btWrKdDaten4_Click_1(object sender, EventArgs e)
    {
      aktkd_id = Program.g_globSettings.IDString;
      DAL dba = new DAL();
      Kunde aktKd = new Kunde();
      // Daten vom GUI nach Bearbeitung in Klasse Kunde übertragen
      aktKd.Id = tbID.Text;
      aktKd.VorName = tbVorname.Text;
      aktKd.NachName = tbName.Text;
      // Klasse zum Schreiben in die Datenbank übergeben
      dba.WriteRec(aktKd);
    }

In "WriteRec" habe ich festgestellt, daß es ohne die Zeile:


SqlCommandBuilder cb = new SqlCommandBuilder(da); 

immer zu der Fehlermeldung "Update requires a valid UpdateCommand when passed DataRow collection with modified rows." bei der Ausführung von


da.Update(ds.Tables[0]);

kommt. Wer verwendet wo die frisch angelegte Instanz namens "cb"?

mfg