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:
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
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
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."
Hallo sinfoe,
- 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
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