Autor Beitrag
toxictype
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 04.04.11 11:50 
Hallo C#ler,
ich finde die Programmierung mit C# und .NET superinteressant und habe mich mit Hillfe des Galileo openbook Visual C# 2008 eingelesen.
Ich habe eine erste Klasse erstellt, die ich künftig für Datenbankanfragen verwenden möchte. Daneben möchte ich noch eine eigene Klassen für DataSets und das Speichern von Daten in Dateien erstellen, auf die ich immer zurück greifen kann.

"Natürlich" sind die ersten Schwierigkeiten aufgetreten und ich würde mich freuen, wenn ihr mir bei der einen oder anderen Sache weiterhelfen könnt. Ich habe die verschieden Operationen (Öffnen, Anfrage und Schliessen der DB) in verschiedene Methoden gesteckt, um ggf. später auf diese einzeln zurückgreifen zu können (s. Code).
Meine erste Frage: Macht das Sinn?

Da ich damit die Objekte SqlConnection inkl. Open, SqlCommand und Close getrennt habe, habe ich Probleme mit der Über- bzw. Rückgabe des SqlConnection-Objekts (s. Code).

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient; // notwendig für das Sql-Connection-Objekt inkl. Exception
using System.Windows.Forms; // notwendig für die MessageBox
using System.Data; // notwendig für das ConnectionState-Objekt

namespace NS_Datenhandling
{
 class Datenbank
 {

  // Klassenvariablen     
  string ConnectionString = "Server = .\\SQLExpress;" +
         "AttachDbFilename=C:\\Programme\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\Kunden.mdf;" +
         "Database=Kunden;" +
         "Trusted_Connection=Yes;";

  // Konstruktor
  Datenbank()
  {
  }

  // Methode zur Verbindungsherstellung
  void verbindeDB() {

   try 
   {
    SqlConnection verbobj = new SqlConnection(ConnectionString);
    if (verbobj.State == ConnectionState.Closed)
    {
     verbobj.Open();
    }
   } 
   catch (System.Data.SqlClient.SqlException ex) 
   {

     MessageBox.Show("Fehler " + ex.Number + " ist aufgetreten: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
   }
  }

  // Methode zum Senden der Abfrage
  int anfrageDB(string strCommandText) 
  {
   try
   {
    SqlCommand abfrageobj = new SqlCommand(strCommandText);
    abfrageobj.Connection = verbobj;

    // bei Auswahlabfragen (SELECT)
    int anzahl = Convert.ToInt32(abfrageobj.ExecuteScalar());

    // bei Aktionsabfragen
    // cmd.ExecuteNonQuery(); -> näheres abchecken

    return anzahl;
   }
   catch (System.Data.SqlClient.SqlException ex)
   {
    MessageBox.Show("Fehler " + ex.Number + " ist aufgetreten: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    return 0;
   }
  }

  // Methode zum Schließen der DB
  void schliesseDB()
  {
   verbobj.Close();
  }

  // Main-Methode (muss diese immer vorhanden sein, auch wenn sie ggf. leer ist???)

  static void Main(string[] args)
  {
   Datenbank dbobj = new Datenbank();
   int anz = dbobj.anfrageDB("SELECT COUNT(*) FROM Kunden"); // COUNT (Abfrage mit nur einem Ergebnis, ExecuteScalar zu testen)
   string txtanz = Convert.ToString(anz);
   dbobj.schliesseDB();

   
   MessageBox.Show(txtanz, "Status Abfrage");
  }
 }
}




Wäre klasse, wenn ihr einen Blick auf die Klasse werft und mir Feedback gebt.

Desweiteren habe ich festgestellt, dass ich mit MS Visual C# Express eine ganze Menge mehr machen kann als nur zu coden. Man kann anscheinend viel, wie z.B. DataSets anlegen mit Hilfe der GUI machen. Gibt es gute Tutorials zur Handhabe von MS Visual C# Express.
So, damit sind die ersten Fragen gestellt.

Vielen Dank für eure Hilfe.

Gruß
tox

Moderiert von user profile iconKha: C#-Tags hinzugefügt
Thommy0606
Hält's aus hier
Beiträge: 15

Win XP
C# (VS2008 Express)
BeitragVerfasst: Di 05.04.11 08:50 
Hallo Tox

Herzlich :welcome:

Zu Deiner Klasse. Es ist aus meiner Sicht schon sinnvoll alles in Klassen zu packen mache ich bei meinen Datenbank abfragen genauso. Allerding verwende ich Access Datenbanken (OLEDB). Wenn dies eine Klasse für viele Projekte sein soll, solltets Du sowohl den Connection String wie auch Den Command String auf Public setzen und jeweils einen Mehtode für OpenConnection und z.B. ReadData generieren. Der OpenConnection Methode übergiebst Du beim Aufruf den Connection String und der ReadData Methode die Command String. Damit ist diese Klasse universell einsetzbar unabhängig von der Datenbank Verbindung und der Abfrage. Du solltest die Datenbankverbindung immer erst bei einer Datenbankaktion z.B. SELECT-Abfrage öffen und nach der Abfrage sofort wieder schliessen. Etwa so (Achtung nur Stielistisch)

conn.Open(); //Verbindung öffnen
Abfage
Datenadabter füllen
conn.Close(); //Verbindung schliessen

Ich hoffe ich habe mich verständlich genug ausgedrückt. Du solltest aus Performance Gründen und auch wegen Programmabstürzen Datenbank Verbindung nie länger offen halten als unbedingt nötig. Damit erübrigt sich auch Deine STATE Abfrage, da die Verbindung ja eh geschlossen ist und ohne Aktion auch geschlossen bleiben sollte. Du solltest die Abfrage aber richtigerweise in einen try-catch Block zusammen fassen.
Zu Deiner Main Methode. Die ist nur in der Klasse notwendig mit der Dein Programm gestartet wird. Diese wird normaler Weise beim erstellen eines neuen Projektes vom Visual Studio angelegt mit asunahme eines leeren Projektes.

Als Bücher kann ich Dir folgende 2 empfehlen wobei ich nicht weiß ob diese noch erhältlich sind.
1. Visual C# 2008 (Komentium) ISBN 978-3-8272-4339-3 Verlag: Markt + Technik
2. Datenbankprogrammierung mit Visual C# 2008 ISBN 978-3-8664-5421-7 Verlag: Microsoft Press
Hilfreich ist auch das C# Codebook ISBN 978-3-8273-2576-1 Verlag: Addison-Wesley

So das waren hoffentlich einige Hilfreiche Informationen für Dich. Bei Fragen bitte melden wenn ich kann versuche ich zu helfen.

Gruß Thomas
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 05.04.11 19:25 
Hallo,

also Du wolltest ja eine ehriche Meinung zu der Klasse haben. Den Sinn der Klasse verstehe ich noch nicht so ganz.
Denn sie macht ja eigentlich (bis jetzt?) nichts weiter, als eine SqlConnection zu öffnen, einen SqlCommand abzusetzen und die Verbindung wieder zu schließen. Und der Command wird durch ein ExecuteScalar abgesetzt. Wenn alles gut läuft, so erhalte ich auch einen Wert zurück. Also wenn ich einen int abgefragt habe oder zufälligerweise ein int in der ersten Zeile, ersten Spalte steht. Ansonsten knallt es. Und der zurückgegebene Wert ist NICHT die Anzahl!!

Mit anderen Worten: die Klasse kann nicht universell eingesetzt werden. Denn mir nützt keine Methode, die ein Command absetzen kann, ich aber das Ergebnis nicht so zurückbekomme, wie ich es benötige.
Es macht schon Sinn, Datenbankabfragen in einer Klasse zu kapseln, aber dann müssen die Abfragen und auch die Rückgabewerte der Methoden bekann sein!

Ansonsten noch ein paar Anmerkungen:
- benenne einen Namespace lieber nicht mit dem Präfix "NS_". Denn die Abkürzung ...
- fange Exceptions erst dort ab, wo sie behandelt werden können/ sollen. Du darfst gerne ein try..finally machen, um die Verbindung zu schließen, aber lass die Exception durchschlagen. Oder fange sie ab und werfe sie dann weiter!
- gebe in so einer Klasse keine MessageBoxen aus. Was, wenn ich die Klasse in einer Konsolenanwendung benutzen will?
- die Main-Methode gehört das nicht rein

Das war es (erstmal). Nicht traurig sein!
LG