Datenbankanwendung verbessern

Die Programmiersprache C# und Programmierung im .NET Framework/Mono
Antworten
Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Datenbankanwendung verbessern

Beitrag von Zenerid » Do Feb 05, 2015 4:26 pm

Hey,

ich habe mit dem MySQL-Connector (C#) und mithilfe des Visual Studios 2012 eine kleine Datenbankanwendung geschrieben, die den MySQL-Connector (C#) benutzt. Dort habe ich allerdings ein paar kleine Umsetzungsprobleme und zudem auch sicherlich vieles, was verbesserungswürdig ist. Deswegen hätte ich mal ein paar kleine Fragen.

1. Ich habe eine einzige Klasse, die die Datenbankoperationen darstellt, also das Hinzufügen von Kunden, Löschen, Bearbeiten usw., vermutlich könnte man das ganze noch besser aufteilen aber wie? Derzeit ist halt wie gesagt alles in dieser einen Klasse.
2. Ich habe in dieser einen Klasse, die übrigens statisch ist eine Verbindung, die überall genutzt wird und zudem ein paar andere. Ist es empfehlenswert eine Verbindung in der Klasse zu haben, die überall genutzt wird? Die meisten Methoden in der Klasse sind ebenfalls static.
Das sieht so aus:

Code: Alles auswählen

private static MySqlConnection sql_connection = new MySqlConnection();
private static MySqlCommand sql_command = new MySqlCommand();
private static MySqlDataReader sql_reader;

static Database()
{
    sql_connection.ConnectionString = Login();
    sql_command.Connection = sql_connection;
}
Jetzt ist muss man natürlich auch immer sql_connection.Open() machen. Könnte man die Offene Verbindung auch irgendwie übergeben oder anderweitig irgendwie das ganze kürzer fassen?

So sieht dann z.B eine der Methoden aus:

Code: Alles auswählen

public static bool DeleteAllData()
{
    sql_command.CommandText = "Delete from Kunde;";

    try
    {
        using (sql_connection)
        {
            sql_connection.Open();
            sql_command.ExecuteNonQuery();
        }
    }
    catch (MySqlException mysqlex)
    {
        // Behandlung
        return false;
    }
    return true;
}
3. Zudem habe ich auch keine interne Repräsentation eines Kunden in meinem Projekt, sondern nur in der DB eine Tabelle für den Kunden. Brauche ich eine eigene Klasse dafür in meinem Projekt, wenn ja wie könnte diese aussehen? Wäre das einfach eine eigene Klasse?

4. Ich habe auch eine eigene Klasse geschrieben, die es ermöglicht die Daten aus der Datenbank in ein XML-File zu exportieren und zu importieren und zudem befindet sich dort auch noch eine Methode, die die Fehler protokolliert (Exceptions) und diese eine Datei schreibt. Derzeit handelt es sich dabei um ein txt.-File. Ist das so üblich?

Ich würde mir auch wahnsinning gerne mal irgendwo fertige Projekte angucken, allerdings sind viele dieser Open-Source Projekte so gigantisch und auch so komplex, das ich fast nichts verstehe.
Hat hier evtl. jemand eine Empfehlung für ein kleineres Projekt, wo man sich auch mal einen guten Stil angucken kann oder eine Seite, wo es solche Projekte gibt? Github und Codeplex etc. kenne ich schon aber wie kann man da auch mal kleienr Projekte finden, die aber trotzdem gut umgesetzt sind?
Diese müssen auch nicht unbedingt eine Datenbankanwendung sein. ;)
Nur ein guter Stil ist mir wichtig, wobei sowas ja auch teilweise Ansichstsache ist aber es gibt ja auch sehr schlecht gibt und zumindest sowas wie "Akzeptabel".

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Datenbankanwendung verbessern

Beitrag von Xin » Fr Feb 06, 2015 2:56 pm

Zenerid hat geschrieben:Deswegen hätte ich mal ein paar kleine Fragen.
Ich bin weder C# Junkie (obwohl offiziell C#-Entwickler ^^) und dass ich das letzte Mal C# mit Datenbanken nutzte ist ziemlich genau 10 Jahre her. ^^
Darum war ich gestern auch etwas zurückhaltender mit der Antwort, falls jemand kompetenteres sich äußern mag.
Zenerid hat geschrieben:1. Ich habe eine einzige Klasse, die die Datenbankoperationen darstellt, also das Hinzufügen von Kunden, Löschen, Bearbeiten usw., vermutlich könnte man das ganze noch besser aufteilen aber wie? Derzeit ist halt wie gesagt alles in dieser einen Klasse.
Ich würde eine Klasse nehmen, die die Datenbank-Transaktionen kapselt und deren Instanz Du entweder Deine Datenobjekte übergibst oder die Du an Deine Datenobjekte übergibst, wohin sie sich schreiben oder initialisieren können.
z.B.

Code: Alles auswählen

Kunde k = new Kunde( dataBase, primaryKey );
Im umgekehrten Fall kannst Du eventuell mit Reflection arbeiten und Funktionalität abstrahieren, aber wäre dann eher was für fortgeschrittene Entwickler.
Zenerid hat geschrieben:2. Ich habe in dieser einen Klasse, die übrigens statisch ist eine Verbindung, die überall genutzt wird und zudem ein paar andere. Ist es empfehlenswert eine Verbindung in der Klasse zu haben, die überall genutzt wird? Die meisten Methoden in der Klasse sind ebenfalls static.
Das sieht so aus:

Code: Alles auswählen

private static MySqlConnection sql_connection = new MySqlConnection();
private static MySqlCommand sql_command = new MySqlCommand();
private static MySqlDataReader sql_reader;

static Database()
{
    sql_connection.ConnectionString = Login();
    sql_command.Connection = sql_connection;
}
Warum machst Du die Sachen statisch?
Du nimmst Dir damit doch die Möglichkeit flexibler mit mehreren Datenbanken zu arbeiten!?
Zenerid hat geschrieben:Jetzt ist muss man natürlich auch immer sql_connection.Open() machen. Könnte man die Offene Verbindung auch irgendwie übergeben oder anderweitig irgendwie das ganze kürzer fassen?

So sieht dann z.B eine der Methoden aus:

Code: Alles auswählen

public static bool DeleteAllData()
{
    sql_command.CommandText = "Delete from Kunde;";

    try
    {
        using (sql_connection)
        {
            sql_connection.Open();
            sql_command.ExecuteNonQuery();
        }
    }
    catch (MySqlException mysqlex)
    {
        // Behandlung
        return false;
    }
    return true;
}
Wenn ich mich recht entsinne muss man die Verbindung nur einmal öffnen. Aber das programmiere ich auch nicht täglich auf's Neue, da müsste ich nachsehen.
Zenerid hat geschrieben:3. Zudem habe ich auch keine interne Repräsentation eines Kunden in meinem Projekt, sondern nur in der DB eine Tabelle für den Kunden. Brauche ich eine eigene Klasse dafür in meinem Projekt, wenn ja wie könnte diese aussehen? Wäre das einfach eine eigene Klasse?
Das sollte eine eigene Klasse sein, die Du zum Beispiel von einer Klasse 'PrimaryKey' ableitest, so dass jeder Kunde weiß, wo er in der Datenbank steht oder dass er noch eingefügt werden muss (bei einem ungültigen PrimaryKey)
Zenerid hat geschrieben:4. Ich habe auch eine eigene Klasse geschrieben, die es ermöglicht die Daten aus der Datenbank in ein XML-File zu exportieren und zu importieren und zudem befindet sich dort auch noch eine Methode, die die Fehler protokolliert (Exceptions) und diese eine Datei schreibt. Derzeit handelt es sich dabei um ein txt.-File. Ist das so üblich?
Ja, das ist jedenfalls nicht unüblich, Fehler in ein .txt-File zu schreiben oder eben an std::cerr zu melden, wenn es sich um ein kleiens Tool handelt. Dann kann der Nutzer flexibler mit den Ausgaben umgehen.
Zenerid hat geschrieben:Ich würde mir auch wahnsinning gerne mal irgendwo fertige Projekte angucken, allerdings sind viele dieser Open-Source Projekte so gigantisch und auch so komplex, das ich fast nichts verstehe.
Hat hier evtl. jemand eine Empfehlung für ein kleineres Projekt, wo man sich auch mal einen guten Stil angucken kann oder eine Seite, wo es solche Projekte gibt? Github und Codeplex etc. kenne ich schon aber wie kann man da auch mal kleienr Projekte finden, die aber trotzdem gut umgesetzt sind?
Diese müssen auch nicht unbedingt eine Datenbankanwendung sein. ;)
Nur ein guter Stil ist mir wichtig, wobei sowas ja auch teilweise Ansichstsache ist aber es gibt ja auch sehr schlecht gibt und zumindest sowas wie "Akzeptabel".
Heutzutage ist alles, was eine erwähnenswerte Funktionalität besitzt bereits 'groß'.
Weiterhin ändert sich die Bedeutung von Codequalität, wenn Projekte groß werden - bei kleinen Projekten spielt sie in der Regel keine Rolle.

Statt Projekte empfehle ich Dir Styleguides zu suchen und Dir anzusehen. Du wirst darin viele gute Tipps finden, die meist auf den Erfahrungen professioneller Entwickler beruhen. Und Du wirst feststellen, dass in vielen widersprüchliches steht und gerade am Anfang wirst Du feststellen, dass manche Styleguides viel zu viel regeln. Das sind die Styleguides aus denen Du Dich bedienen solltest.
Auch wenn Dir die Frage ob es

Code: Alles auswählen

if (4==value) {
  ...
}
oder

Code: Alles auswählen

if( value == 4 )
{
  ...
}
heißt für Dich erstmal unwichtig ist, da sind bereits drei Fragen drin, über die sich erfahrene Entwickler lange und ausführlich streiten können... und auch schon seit vielen Dekaden tun, ohne zu einem Ergebnis zu kommen. ;-)

Da es den einen guten Stil nicht gibt, musst Du Dir selbst einen Kopf machen, was für Dich gut lesbar ist und funktioniert.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Datenbankanwendung verbessern

Beitrag von Zenerid » Sa Feb 21, 2015 3:48 am

Hey,

ich habe ja eine eigene Klasse für diese Datenbankoperationen aber das alles komplett in einer Klasse, also bearbeiten löschen usw oder wie meinst du das?

Warum sollte man denn die Datenbankklasse nicht statisch machen? Dadurch muss man nicht immer eine Instanz der Klasse erzeugen und wieso sollte man mit mehreren Datenbanken zur gleichen Zeit arbeiten? Macht man nicht in der Regel für ein Projekt eine Datenbank? Ich kenne das wohl, das man mit mehreren Tabellen arbeitet aber mit mehreren Datenbanken, wieso?

Ich verstehe auch nicht, warum man überhaupt eine interne Repräsentation eines Kunden in einem Projekt braucht. Wieso lässt man das ganze nicht einfach in der Datenbank, was hat das für einen Vorteil, wenn ich einen Kunden in meinem Projekt als Klasse habe?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Datenbankanwendung verbessern

Beitrag von cloidnerux » Sa Feb 21, 2015 10:03 am

ich habe ja eine eigene Klasse für diese Datenbankoperationen aber das alles komplett in einer Klasse, also bearbeiten löschen usw oder wie meinst du das?
Das ist schon richtig.
Die Idee ist ja, dass du den Zugriff auf die Datenbank kapselst, dann darüber musst du dir an anderer Stelle keine Gedanken machen. Wichtiger ist aber, dass du die direkten Datenbankzugriffe im Auge behalten kannst. Stell dir vor du hast überall im Code irgendwelche

Code: Alles auswählen

FROM table FETCH * WHERE ID=1
verteilt und einer macht Probleme, frohes suchen.
Oder du stellst fest, dass dein Programm nicht sicher ist vor SQL-Injections, dann Update mal alle Datenbankzugriffe.

Insgesamt geht es also nicht nur um das Bereitstellen der Datenbankverbindung, sondern auch das Plausabilisieren der Datenbankoperationen.
Warum sollte man denn die Datenbankklasse nicht statisch machen?
Weil es schlechter Stil ist.
Auch wenn du jetzt nur eine Datenbank hast, kann sich das irgendwann mal ändern.
Vielleicht willst du den Datenbestand in eine neue Datenbank portieren und auf einmal brauchst du zwei Datenbanken.
Dadurch muss man nicht immer eine Instanz der Klasse erzeugen
Ich hoffe ja nicht, dass du das versuchst.
Normalerweise legst du das Datenbankobjekt an einer Stelle an und übergibst es dann den Klassen die es brauchen.
Geht in Richtung "Singleton".
Ich verstehe auch nicht, warum man überhaupt eine interne Repräsentation eines Kunden in einem Projekt braucht. Wieso lässt man das ganze nicht einfach in der Datenbank, was hat das für einen Vorteil, wenn ich einen Kunden in meinem Projekt als Klasse habe?
Du musst zwangsweise die Daten aus der Datenbank holen, damit musst du die auch irgendwie intern Speichern, das ist Punkt 1.
Nun will ein Nutzer auch Operationen auf den Datenbestand ausführen, suchen, verknüpfen, einfügen, löschen, etc.
Und mach für all das eine neue Anfrage an der Datenbank.

Wenn du das Datenmodell aus der Datenbank lokal hast, kannst du per LINQ und anderen Operationen direkt die Daten lokal ändern und per Property-Changed Events neue Daten direkt in die Datenbank schreiben, fallst du das möchtest.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Antworten