T-Back Geschrieben 14. März 2009 Teilen Geschrieben 14. März 2009 Hallo Leute, ich bin neu hier im Forum und möchte einmal alle begrüßen und sich bei allen Bedanken, die anderen Leuten immer wieder helfen und Ihre Erfahrungen hier herein schreiben!!! Nun zu meinem Problem: Ich habe ein Datenbank-Client Projekt entwickelt bzw. ich bin gerade dabei und habe ein Problem mit allen DataGridView's! Die DGVs zeigen beim Debuggen keine Daten von der Datenbank an. Das Programm besteht aus 2 Klassenbibliotheken, der libDAL (DataAccessLayer) und der libBL (BusinessLogic), und aus einer Windows-Forms Anwendung. Der Datenbank-Zugriff der DataGridView ist Objekt-basierend. Das komische ist, dass das DataGridViews jeweils pro Datenbank-Tabelle den Primary Key (habe ich als int deklariert) und einen bool-Datentyp anzeigt mittels einer Checkbox. Das DataGridView zeigt auch genau so viele Zeilen an, wie die Datenbank hat! Ich habe jeweils eine zweite Windows Form erstellt, um die Daten aus dem DataGridView zu ändern, also zum NEU hinzufügen eines Datensatzes und um einen Datensatz zu BEARBEITEN. In einer Windows Form von diesen habe ich zwei verschiedene BindingSources implementiert um in einer ComboBox, die Daten einer anderen Tabelle anzuzeigen. UND DAS FUNKTIONIERT! Wenn ich einen neuen Datensatz erstelle und danach in der Windows Form mit dem DGV mittels einem Button eine Gespeicherte Prozedur bspw. "UPDATE" ausführe, dann zeigt das DataGridView die neue Zeile an und den fortlaufenden Primary Key, der immer um 1 erhöht wird. Die NEUEN Daten sind auch in der Datenbank zu sehen, wenn ich eine Tabelle öffne in der "Microsoft SQL Server Express Edition"! Ich habe schon einmal ein Projekt nach dem gleichen Schema programmiert, und dort funktioniert der Datenzugriff ganz normal! Beide Projekte sind in C# und mit dem VS 2008 erstellt worden. Ich bin über jeden Tipp und über jeden Ratschlag den Ihr mir geben könnt sehr dankbar! LG T-Back Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 15. März 2009 Autor Teilen Geschrieben 15. März 2009 Könnte mir bitte jemand weiterhelfen? Ich bin schon am verzweifeln! MFG Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Gooner85 Geschrieben 16. März 2009 Teilen Geschrieben 16. März 2009 Ich verstehe nicht ganz, wo Dein Problem liegt. Kannst Du uns das vielleicht noch mal erläutern, denn aus der obigen Beschreibung geht es (zumindest für mich) nicht hervor. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 17. März 2009 Autor Teilen Geschrieben 17. März 2009 Danke für eure Hilfe! Also mein Programm besteht aus drei Projekten: 1.) DataAccessLayer (Klassenbibliothek) 2.) BusinessLogic (Klassenbibliothek) 3.) GUI (Windows Form Projekt) In der Klasse DAL.cs (diese befindet sich im DataAccessLayer-Projekt) habe ich die Verbindung zur Datenbank hergestellt mittels einigen Methoden: using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace libDAL { public class DAL { public static SqlConnection DBconn() { // Verbindungssettings aus der app.config lesen und zurückgeben. return new SqlConnection(ConfigurationManager.ConnectionStrings["PrivateBuchverwaltung"].ConnectionString); } public static SqlParameter DBparameter(string sVariablenName, object oWert) { return new SqlParameter(sVariablenName, oWert); } // Prozedur Methode - StoredProcedure Methode public static void ExecuteNonQuerySP(string sStoredProcedureName, params SqlParameter[] SqlPar) { SqlCommand cmd = new SqlCommand(sStoredProcedureName, DAL.DBconn()); cmd.CommandType = CommandType.StoredProcedure; // Parameter zum Command hinzufügen foreach (SqlParameter p in SqlPar) { cmd.Parameters.Add(p); } // Daten abrufen cmd.Connection.Open(); // Methode der Klasse SqlCommand, um DateSätze einzufügen oder zu ändern. Sie liefert die Anzahl der Zeilen, die durch das // Kommando geändert wurden zurück. Das gilt für UPDATE, DELETE und NEW, bei anderen Kommandos liefert sie den Wert -1 zurück. // TODO: SPs in DAL SQL-Exception wurde nicht behandelt bei "Neuen BuchTitel" // TODO: SPs in DAL: Meldung: Die Prozedur oder Funktion 'spBuchTitelnNEW' erwartet den '@ISBN10'-Parameter, der nicht bereitgestellt wurde. cmd.ExecuteNonQuery(); // Verbindung schließen! cmd.Connection.Close(); } public static DataTable ExecuteDataTableView(string sSQL, params SqlParameter[] SqlPar) { DataTable dt = new DataTable(); SqlCommand cmd = new SqlCommand(sSQL, DAL.DBconn()); cmd.CommandType = CommandType.Text; // Parameter zum Command hinzufügen foreach (SqlParameter p in SqlPar) { cmd.Parameters.Add(p); } SqlDataReader dr; cmd.Connection.Open(); dr = cmd.ExecuteReader(); // Daten vom DataReader in die Tabelle übergeben! dt.Load(dr); cmd.Connection.Close(); return dt; } } } // Die Methode ExecuteReader liefert ein Objekt des SqlDataReaders zurück // und wird verwendet bei "SELECT" - Abfragen. // TODO: SQL - Exception kommt hier immer wieder MELDUNG: Falsche Syntax in der Nähe von '=' Fortsetzung folgt: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 17. März 2009 Autor Teilen Geschrieben 17. März 2009 Die Verbindung mit der Datenbank ist gegeben, habe ich mittels einer "Testverbindung" probiert. Die Datenbindung erfolgt mit Objekten, hierfür habe ich das BusinessLogic Projekt erstellt. Hier ist eine Klasse der BL: using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; using System.IO; using System.Data; using libDAL; namespace libBL { public class cAutor : cBLBasis { #region Properties private int AutorID_; public int AutorID { get { return AutorID_; } } private string sZuname_; public string sZuname { get { return sZuname_; } set { sZuname_ = value; } } private string sVorname_; public string sVorname { get { return sVorname_; } set { sVorname_ = value; } } private string sEmail_; public string sEmail { get { return sEmail_; } set { sEmail_ = value; } } private string sHomepage_; public string sHomepage { get { return sHomepage_; } set { sHomepage_ = value; } } #endregion #region Methoden fuer die Stored Procedures public void SAVE() { if (this.bNeu) { DAL.ExecuteNonQuerySP("spAutorenNEW", DAL.DBparameter("@Zuname", this.sZuname), DAL.DBparameter("@Vorname", this.sVorname), DAL.DBparameter("@Email", this.sEmail), DAL.DBparameter("@Homepage", this.sHomepage)); this.bNeu = false; } else { DAL.ExecuteNonQuerySP("spAutorenUPDATE", DAL.DBparameter("@AutorID", this.AutorID), DAL.DBparameter("@Zuname", this.sZuname), DAL.DBparameter("@Vorname", this.sVorname), DAL.DBparameter("@Email", this.sEmail), DAL.DBparameter("@Homepage", this.sHomepage)); } } public void DELETE() { DAL.ExecuteNonQuerySP("spAutorenDELETE", DAL.DBparameter("@AutorID", this.AutorID)); } #endregion #region "static" - Methoden public static DataTable GetAutorenListe() { return DAL.ExecuteDataTableView("SELECT * FROM tblAutoren"); } public static cAutor GetAutorByID(int AutorID) { cAutor A = new cAutor(); DataTable dtEinzelnerAutor = DAL.ExecuteDataTableView("SELECT * FROM tblAutoren" + "WHERE AutorID = @AutorID", DAL.DBparameter("@AutorID", AutorID)); if (dtEinzelnerAutor.Rows.Count > 0) { DataRow dr = dtEinzelnerAutor.Rows[0]; A.sZuname = dr["Zuname"].ToString(); A.sVorname = dr["Vorname"].ToString(); A.sEmail = dr["Email"].ToString(); A.sHomepage = dr["Homepage"].ToString(); A.AutorID_ = (int)dr["AutorID"]; } return A; } public static DataTable GetVollenNamen() { return DAL.ExecuteDataTableView("SELECT * FROM tblAutoren ORDER BY Zuname + ' ' + Vorname;"); } #endregion } } Fortsetzung folgt: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 17. März 2009 Autor Teilen Geschrieben 17. März 2009 Im Projekt GUI, wo die DataGridView's sind habe ich das Projekt BusinessLogic mittels der using-Anweisung eingebunden. Beim hinzufügen von Datenquellen, habe ich beim Assistenten "OBJEKT" ausgewählt, so dass die DGVs mit einer BindingSource verbunden sind. Hier sind noch zwei Klassen aus dem Projekt GUI: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; //using System.Linq; using System.Text; using System.Windows.Forms; using libBL; namespace BuchVerwaltung { public partial class frmBuchListe : Form { public frmBuchListe() { InitializeComponent(); } #region Von Windows.Forms aufgerufene Methoden // FORM - LOAD private void frmBuchListe_Load(object sender, EventArgs e) { dgvBuecher.AutoGenerateColumns = false; dgvBuecher.DataSource = cBuchtTitel.GetTitelListe(); } // Doppelklick ZELLE private void dgvBuecher_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { BuecherBearbeiten(); } // BEARBEITEN-BUTTON private void btnBearbeiten_Click(object sender, EventArgs e) { // Methode (Prozedur) "BuecherBearbeiten" aufrufen BuecherBearbeiten(); } private void btnNeu_Click(object sender, EventArgs e) { // Objekt der Klasse "cBuchTiteln" erstellen cBuchtTitel Titel = new cBuchtTitel(); // Objekt der Klasse "frmBuchDetails" erstellen frmBuchDetails BuchDetails = new frmBuchDetails(); BuchDetails.cBuchtTitelBindingSource.DataSource = Titel; if (BuchDetails.ShowDialog() == DialogResult.OK) { // Neuen Record anlegen Titel.bNeu = true; Titel.SAVE(); } } // LÖSCHEN - BUTTON private void btnLoeschen_Click(object sender, EventArgs e) { if (AktuelleZeileID() == 0) { MessageBox.Show("Sie müssen zum Löschen eine Zeile markieren!", "INFORMATION", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); return; } if (MessageBox.Show("Möchten Sie dieses Buch wirklich\n aus der Datenbank löschen?", "LÖSCHEN", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3) == DialogResult.OK) { cBuchtTitel Buch = new cBuchtTitel(); Buch.DELETE(); DatenNeuLaden(); } } private void btnNeuLaden_Click(object sender, EventArgs e) { DatenNeuLaden(); } #endregion #region Selbst geschriebene Methoden // EIGENE PROZEDUR private void DatenNeuLaden() { // --> Alle Bücher, die in der DB gespeichert sind anzeigen, mit Hilfe der // Eigenschaft "+DataSource" des DataGridView Objektes // ERKLÄRUNG - "DataSource" - Ruft die Datenquelle ab, für die das DataGridView DATEN anzeigt. dgvBuecher.DataSource = cBuchtTitel.GetTitelListe(); } // EIGENE PROZEDUR private void BuecherBearbeiten() { if (AktuelleZeileID() == 0) { // Der User muss eine Zeile markieren! MessageBox.Show("Bitte markieren Sie eine Zeile!", "INFORMATION", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } cBuchtTitel GewaehlterTitel = cBuchtTitel.GetTitelnByID(AktuelleZeileID()); // Die Klasse "frmBuchDetails" instanzieren und ein neues Objekt erstellen. frmBuchDetails BuchDetails = new frmBuchDetails(); BuchDetails.cBuchtTitelBindingSource.DataSource = GewaehlterTitel; if (BuchDetails.ShowDialog() == DialogResult.OK) { MessageBox.Show("Möchten Sie die Änderungen speichern?","SPEICHERN", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); // SPEICHERN GewaehlterTitel.SAVE(); } } // EIGENE FUNKTION private int AktuelleZeileID() { // Wenn keine Zeile markiert ist dann ... if (dgvBuecher.CurrentRow == null) { // Keine Zeile markiert return 0; } // Wenn eine Zeile markiert ist dann .... else { // DataRowView stellt eine benutzerdefinierte Ansicht einer DataRow dar. // DataBoundItem ruft das datengebundene Objekt ab, mit dem die Zeile aufgefüllt wird. DataRowView drv = (DataRowView)dgvBuecher.CurrentRow.DataBoundItem; // Rückgabe return (int)drv["TitelID"]; } } #endregion } } Hier ist der Quellcode aus der Windows Form "frmBuchDetails": using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; //using System.Linq; using System.Text; using System.Windows.Forms; using BuchVerwaltung.Properties; using libBL; namespace BuchVerwaltung { public partial class frmBuchDetails : Form { public frmBuchDetails() { InitializeComponent(); } // FORM - LOAD private void frmBuchDetails_Load(object sender, EventArgs e) { cbVerlag.DataSource = cVerlag.GetVerlagListe(); cbVerlag.DisplayMember = "Verlag"; cBuchtTitel BuchTitel = (cBuchtTitel)cBuchtTitelBindingSource.Current; } private void btnOk_Click(object sender, EventArgs e) { if (txtTitel.Text.Trim().Length == 0 || txtBuchGenre.Text.Trim().Length == 0) { MessageBox.Show("Sie müssen den Titel des Buches und sein Genre angeben!", "INFORMATION", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } cBuchtTitel Buch = (cBuchtTitel)cBuchtTitelBindingSource.Current; Buch.VerlagID = cAllgemeines.ZeilenID(cbVerlag.SelectedItem, "VerlagID"); this.DialogResult = DialogResult.OK; } private void btnAbbrechen_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; } } } Des weiteren habe ich "Hinzufügen, Bearbeiten und Löschen aktivieren" im DataGridView mit der CheckBox Deaktiviert! Nun kann ich alle Klassen, die in der "BL"geschrieben habe als Datenquelle hinzufügen. Das Programm ansich funktioniert, bis auf ein paar SQL-Exceptions, die wahrscheinlich an den Stored Procedures liegen und mein HAUPT-PROBLEM, dass die DGVs nur die ID's anzeigen, die ich als int Datentyp deklariert habe. Ich bin schon am Verzweifeln!! Ich hoffen Ihr könnt mir weiterhelfen, das währe echt sehr nett! Und ich hoffe ich habe nicht gegen die Forenregeln verstoßen, indem ich eine Antwort auf 3 Antworten aufgeteilt habe? Ich bin für jeden Tipp und Ratschlag sehr dankbar! MFG Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Gooner85 Geschrieben 17. März 2009 Teilen Geschrieben 17. März 2009 Welche Datenbank verwendest Du denn? Soweit ich das sehe, ist es einfacher die ID als PrimaryKey zuweisen zulassen. Das heißt, immer wenn Du einen neuen Eintrag einfügst erhält dieser eine neue ID. Dadurch musst Du keine ID-Zuweisung im Quellcode schreiben. Bei MS SQL Server kann man diese Einstellung bei den Table-Definitions vornehmen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 17. März 2009 Teilen Geschrieben 17. März 2009 Das Programm ansich funktioniert, bis auf ein paar SQL-Exceptions, die wahrscheinlich an den Stored Procedures liegen und mein HAUPT-PROBLEM, dass die DGVs nur die ID's anzeigen, die ich als int Datentyp deklariert habe. Da ich faul bin und mir weder deinen Quelltext durchlesen will, noch irgendwie deine ERMs kenne, würden mich die Exceptionmessages mal interessieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 17. März 2009 Autor Teilen Geschrieben 17. März 2009 Danke für eure Antworten! @Gooner85 Ich verwende den SQL-Server 2005 "Express-Edition". Das mache ich sowieso, dass ich den Primary Key als fortlaufende Zahl zuweisen lasse. Das habe ich im SQL-Server unter "Identitätsspezifikation" --> is Identity auf True gestellt und jetzt ist er eine fortlaufende Zahl, die immer um eins erhöht wird und bei 1 beginnt. Mit dem habe ich kein Problem, mein Problem ist, dass ich im DataGridView eben nur den Primary Key zu sehen bekomme. Und im Programm selbst musste ich den Primary Key (ID) implementieren, diesen habe ich als int deklariert, da ich in der BusinessLogic für jede DB-Tabelle jeden Spalten-Namen als Property und Feld ausprogrammiert habe. Natürlich habe ich den Primary Key jeder Tabelle als Schreibgeschützt programmiert (also nur die "get{}"-Anweisung geschrieben). Das ganze habe ich gemacht, da das DataGridView und alle anderen Windows Forms Elemente die Datenbank-Bindung über eine BindingSource Komponente erhalten. Die BindingSource ist dann jeweils für jede DB-Tabelle eine Klasse in BusinessLogic. Diese habe ich bei "Datenquelle hinzufügen" über Projektdatenquelle hinzugefügt. Ich habe bei Datenquelle nur meine Projektdatenquellen, nicht die Datenbank direkt. Und irgendetwas mache ich falsch, da nur die Primary Key's in den DGVs angezeigt werden, und alle anderen Spalten sind leer. Ich bin euch sehr dankbar für jede Hilfe!!! MFG Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Gooner85 Geschrieben 17. März 2009 Teilen Geschrieben 17. März 2009 Ich kenne mich leider nicht besonders gut mit ExecuteReader aus. Deshalb würde ich Dir empfehlen, das ganze mittels DataAdapter, DataSet & DataTable zulösen. Im DataAdapter packst Du die Connection & Abfrage. Du kannst es natürlich auch mit Command machen. Das sieht dann ungefähr so aus: Dim Con As SqlClient.SqlConnection = New SqlClient.SqlConnection _(>Connection-String<) Dim Adapter As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter _(>SQL-Abfrage<, Con) Anschließend deklarierst Du ein ein DataSet, füllst dieses mit der Fill-Methode und dann kannst Du deine Tabellen im GridView ausgeben. 'DataSet Dim DS As New DataSet Adapter.Fill(DS, "Table1") DataGridView1.DataSource = DS DataGridView1.DataMember = "Table 1" "Table1" ist hierbei der Name Deiner Tabelle im DataSet. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
T-Back Geschrieben 24. März 2009 Autor Teilen Geschrieben 24. März 2009 Hallo, Ich habe es schon zusammengebracht, dass das DataGridView Daten anzeigt! Mit der Anweisung: dgv.autogeneratecolums = true; Ich hätte eine Bitte an euch, könntet Ihr euch evtl. meinen Code kurz durchschauen, da ich einige Probleme noch in meiner Anwendung habe: 1.) Wenn ich die Stored Procedure "DELETE" ausführen möchte funktioniert diese bei KEINER Tabelle! Ich habe aber alle SPs im SQL-Server Managemant Studio getestet, also DB-mäßig stimmen alle Parameter der Prozedur. 2.) Wenn ich bestimmte SQL Anweisungen im Programm ausführen möchte, z.Bsp. einen Datensatz bearbeiten, dann kommt eine SqlException mit der Fehlermeldung: Falsche Syntax in der Nähe von '='. in der Methode ExecuteDatatableView() die sich in der Klasse DAL.cs befindet. Diese Klasse ist für die Verbindung zur Datenbank mit den Objekten wie SqlConnection, SqlCommand, SqlDataReader, usw... Hier werden die Verbindungen geöffnet und geschlossen. Ich stelle sie hier herein. Ich bin für jeden Verbesserungsvorschlag, Ratschlag und Tipp sehr dankbar! Dann hätte ich noch eine Frage, wo finde ich die Nummern der Fehlermeldungen, wenn ich einen try-catch Block einbaue mit einem SqlException Objekt im catch Block. Die Klasse DAL.cs using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace libDAL { public class DAL { public static SqlConnection DBconn() { // Verbindungssettings aus der app.config lesen und zurückgeben. return new SqlConnection(ConfigurationManager.ConnectionStrings["PrivateBuchverwaltung"].ConnectionString); } public static SqlParameter DBparameter(string sVariablenName, object oWert) { return new SqlParameter(sVariablenName, oWert); } // Prozedur Methode - StoredProcedure Methode public static void ExecuteNonQuerySP(string sStoredProcedureName, params SqlParameter[] SqlPar) { SqlCommand cmd = new SqlCommand(sStoredProcedureName, DAL.DBconn()); cmd.CommandType = CommandType.StoredProcedure; // Parameter zum Command hinzufügen foreach (SqlParameter p in SqlPar) { cmd.Parameters.Add(p); } // Daten abrufen cmd.Connection.Open(); // Methode der Klasse SqlCommand, um DateSätze einzufügen oder zu ändern. Sie liefert die Anzahl der Zeilen, die durch das // Kommando geändert wurden zurück. Das gilt für UPDATE, DELETE und NEW, bei anderen Kommandos liefert sie den Wert -1 zurück. // TODO: SPs in DAL SQL-Exception wurde nicht behandelt bei "Neuen BuchTitel" // TODO: SPs in DAL: Meldung: Die Prozedur oder Funktion 'spBuchTitelnNEW' erwartet den '@ISBN10'-Parameter, der nicht bereitgestellt wurde. cmd.ExecuteNonQuery(); // Verbindung schließen! cmd.Connection.Close(); } public static DataTable ExecuteDataTableView(string sSQL, params SqlParameter[] SqlPar) { DataTable dt = new DataTable(); SqlCommand cmd = new SqlCommand(sSQL, DAL.DBconn()); cmd.CommandType = CommandType.Text; // Parameter zum Command hinzufügen foreach (SqlParameter p in SqlPar) { cmd.Parameters.Add(p); } SqlDataReader dr; cmd.Connection.Open(); dr = cmd.ExecuteReader(); // Daten vom DataReader in die Tabelle übergeben! dt.Load(dr); cmd.Connection.Close(); return dt; } } } // Die Methode ExecuteReader liefert ein Objekt des SqlDataReaders zurück // und wird verwendet bei "SELECT" - Abfragen. // TODO: SQL - Exception kommt hier immer wieder MELDUNG: Falsche Syntax in der Nähe von '=' DANKE!!! MFG Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.