Laden...

3-Tier, verschiedene DBMS

Erstellt von MAjbO vor 18 Jahren Letzter Beitrag vor 13 Jahren 3.041 Views
M
MAjbO Themenstarter:in
97 Beiträge seit 2004
vor 18 Jahren
3-Tier, verschiedene DBMS

Hi Leute

Der Titel ist nicht besonders gut und ich bin mir auch nicht sicher, ob das Forum das richtige ist. Einfach umbenennen/verschieben 😉

Zu meiner Frage...
Ich habe vor, ein Programm zu schreiben, dass mit verschiedenen DBMS arbeitet. Nun ist es mir mit dem 3-Tier-Modell soweit klar, dass ich
-GUI
-BLL
-DAL
habe, aber wo und wie richte ich es jetzt ein, dass mein DAL in der Lage ist, auf verschiedene DBMS zuzugreifen? Ich brauche für die verschiedenen DBMS jeweils angepasste SQL-Querrys.
Meine erste überlegung war gewesen, pro DBMS eine DAL-Klasse zu schreiben. Aber dann muss der BLL ja auch jeweils wissen, mit welchem DBMS gearbeitet wird, was dem Modell IMO widerspricht.

Gruss
MAjbO

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo MAjbO,

Meine erste überlegung war gewesen, pro DBMS eine DAL-Klasse zu schreiben.

Die Idee ist gut.

Aber dann muss der BLL ja auch jeweils wissen, mit welchem DBMS gearbeitet wird

Nein, dass ist nicht nötig. Es gibt entsprechende Design-Pattern, um diese Abhängigkeit zu vermeiden, z.B. Abstract Factory o.ä.

herbivore

M
MAjbO Themenstarter:in
97 Beiträge seit 2004
vor 18 Jahren

Hi herbivore

Danke für deine Antwort. Das Stichwort Abstract Factory bringt bei Google ein par interessante ergebnisse. Aber irgendwie ist mir das alles zu theoretisch bzw. ich weiss nicht, wie ich das konkret auf mein (C#) Projekt anwenden kann.
Könntest du evt. ganz kurz erläutern, wie du dir das vorgestellt hast, oder mir noch ein par Google-Stichworte sagen?

Gruss
MAjbO

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo MAjbO,

vom Prinzip und etwas vereinfacht: du schreibst eine abstrakte Klasse, die alle Methode definiert, die der DAL braucht. Dann schreibst du je eines DBMS eine konkrete Klasse, die die Methoden für das jeweilige DBMS implementiert. Dann ist die einzige Stelle, die vom jeweiligen DBMS abhängig ist, die, wo das konkrete Objekt erzeugt wird. Im einfachsten Fall, gibt es eine Methode, die den Namen der konkreten Klasse aus eine Konfigurationsdatei ausliest und eben dieses konkrete Objekt erzeugt. Das würde z.B. per Reflection gehen. Wie gesagt, etwas vereinfacht. Wenn man die entsprechenden Design-Pattern verwendet, kriegt man da auch ein sauberes Design hin.

herbivore

M
MAjbO Themenstarter:in
97 Beiträge seit 2004
vor 18 Jahren

Hi herbivore

Nochmals danke für deine Antwort, komme erst jetzt dazu, an meinem (privaten) Projektchen weiterzuarbeiten 😉
Habe mich mal ein wenig schlau gemacht und nun folgende Struktur:

GUI-Layer
-Alle Form-Klassen
BLL-Layer
-Database-Klasse und "kleinkram"
DAL-Layer
-Interface "IDAL"
-DAL-Klassen, die IDAL implementieren

Das funktioniert soweit bestens und ist ja deinem Vorschlag sehr änlich. Nun habe ich wieder eine kleine "Denkblockade".
Ich wollte mir für die verschiedenen DBMS ein enum schreiben, so in etwa:

enum ServerType { MSSQL2000, MSSQL2005,  MySQL50 };

Nur weiss ich jetzt nicht, wo ich das reinpacken soll. Denn diesen Servertype benötige ich im Prinzip in allen 3 Layern. Wie macht man sowas am saubersten?

Gruss
MAjbO

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo MAjbO,

wenn du den enum in den DAL packst, wo er ja inhaltlich reingehört, dann steht er ja in den Schichten darüber zur Verfügung.

herbivore

M
MAjbO Themenstarter:in
97 Beiträge seit 2004
vor 18 Jahren

Hm, macht Sinn 😉

Hab jetzt in meinem DAL-Projekt eine Datei namens Enums.cs mit folgemdem Inhalt:

namespace Generator.DAL
{
    public enum ServerType { MSSQL2000, MSSQL2005, MySQL50 };
}

Funktioniert bestens, danke 🙂

185 Beiträge seit 2007
vor 13 Jahren

Ich würde mich hier gerne anschließen, da die letzten Postings exakt meiner Fragestellung matchen und hier liegt auch schon das Problem:

wenn du den enum in den DAL packst, wo er ja inhaltlich reingehört, dann steht er ja in den Schichten darüber zur Verfügung.

Vom Business Layer aus kann ich noch auf die im DAL definierten enums zugreifen, vom Presentation Layer aus allerdings nicht mehr:

(Fehlermeldung einer Klasse aus dem Presentation Layer)
"Der Typname 'MyEnum' ist im Typ 'MyBusinessLayer' nicht vorhanden"

Der Presentation Layer enthält keinen Verweis auf den DAL, dies ist von der Architektur her doch so gewollt und auch sinnig oder?

Wie muss ich meine Klasse und/oder meinen Enum deklarieren, sodass er im Presentation Layer zur Verfügung steht?

Kurzes Snippet, wie meine Struktur aussieht:



using BLL;

namespace GUI
{
    public class GUI
    {
         // BLL.DAL.Modes?! Wie zugreifen?
    }
}
______________________________________________

using DAL;

namespace BLL
{
    public class BLL
    {
         // DAL.Modes-Zugriff klappt.
    }
}

______________________________________________

namespace DAL
{
    public class DAL
    {
        public enum Modes
        {
            Standard = 1,
            NichtStandard = 2,
            NochWasAnderes = 3
        }
    }
}


1.378 Beiträge seit 2006
vor 13 Jahren

Ich halte es in meinem aktuellen Projekt nicht so strikt: Hauptsache von Oben nach Unten und nicht umgekehrt. Dabei überspring ich schon mal den BL um auf den DAL zuzugreifen. Entweder das, oder du lagerst sowas aus in eine extra Assembly die dann über alle Schichten erreichbar ist(shared).

Lg XXX

799 Beiträge seit 2007
vor 13 Jahren

Warum willst du auf den DAL überhaupt zugreifen?

Deine Zugriffe auf das DAL sollten über den Umweg des BLL funktionieren.

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl
185 Beiträge seit 2007
vor 13 Jahren

Ist mir schon klar.

Nur diese "Modes" sind halt nicht nur für den Data Access relevant, sondern auch für einzelne UserControls, wie die Daten "anders" angezeigt werden bspw.


Shared:

  • nochmalig Strukturen aus dem Kontext reißen, was mich an der 3-Tier-Architektur an sich schon etwas gestört hat

Direkter Zugriff auf DAL:

  • Damit zerstört man doch fast den Sinn des Modells oder? Kommt aber auch wirklich auf konkrete Dinge an, manchmal geht es halt nicht anders oder man tunnelt die Methoden und erstellt sie nochmals im BLL, sodass die Aufrufe durchgeleitet werden.

Habe mich jetzt für eine dritte Variante entschieden:

Enums in den BLL und vom BLL an den DAL übergebe ich nur die int-Werte.

U
282 Beiträge seit 2008
vor 13 Jahren

Nur diese "Modes" sind halt nicht nur für den Data Access relevant, sondern auch für einzelne UserControls, wie die Daten "anders" angezeigt werden bspw.

Wobei das natürlich das ganze Konzept etwas ad absurdum führt. Die Idee ist ja, dass die BLL und GUI nicht von dem konkreten DAL kennt, sondern nur das Intrerface. Wenn nun die GUI für jeden DAL anders ist, ist das Design zumindest fragwürdig.

Habe mich jetzt für eine dritte Variante entschieden:
Enums in den BLL und vom BLL an den DAL übergebe ich nur die int-Werte.

Mmmmh.... Ich finde das Shared-Assembly da eigentlich schöner. Wobei ich deine Probleme damit verstehen kann. Man muss halt aufpassen, dass da echt nur dumme Datentypen reinkommen und man nicht anfgängt, irgendwann alles in das Shared-Assembly reinzupacken.

185 Beiträge seit 2007
vor 13 Jahren

Ich würde nicht das Design/GUI in Frage stellen wollen, sondern eher die Struktur meines DALs.

Innerhalb meiner DAL-Methoden baue ich SQLs zusammen und hier kommen die Modes/Enums ins Spiel, je nach Modus wird zur SQL-Abfrage etwas anderes hinzugefügt oder weggelassen (StringBuilder).

Jetzt könnte man natürlich im BLL den Modus abfragen und für jeden Modus eine eigene Methode im DAL anlegen, dann hätte ich aber relativ häufig die selben SQL-Bestandteile (Duplikate innerhalb der unterschiedlichen Methoden).

Ich tue mich sehr schwer damit, was ich wo, wie hinpacke und aufsplitte, merkt man das?

Hoffe du/ihr schreibt noch einmal ein paar Sätze dazu.

// Edit: Ich stelle mir auch schon länger die Frage, ob das zusammenbauen von SQL überhaupt in den DAL gehört? Einerseits ja, die Methoden liefern mir die strukturierten Daten, welche ich im BLL weiterverarbeite. Andererseits könnte man auch "nein" sagen, wenn im DAL ausschließlich Klassen für den DatenZUGRIFF abgelegt werden sollen. Kann jemand dazu vielleicht auch ein Statement abgeben?

1.378 Beiträge seit 2006
vor 13 Jahren

Naja das ist eindeutig DAL Thema und hat eigentlich die BL nicht zu interessieren wo und wie die Daten daher kommen.

Meiner Meinung nach, sollte der DAL die Daten so aufbereiten wie er es für richtig hält und die BL muss damit zurecht kommen ebenso wie die GUI wenn eine DAL Methode unterschiedliche Results zurückgeben kann.

Inwiefern hat der Parameter denn Auswirkungen auf die GUI bzw. den BL? Evt. ist die DAL Methode zu überdenken.

Lg XXX

185 Beiträge seit 2007
vor 13 Jahren

Labels haben andere Inhalte, TreeView-Controls laden unterschiedliche Inhalte nach, usw.

Auf DAL-Ebene hat es Auswirkung auf den generierten Report / auf die Verdichtung der Daten.

1.378 Beiträge seit 2006
vor 13 Jahren

So wie das für mich aussieht, ist dein Enum eine Applikationseinstellung(oder irre ich mich da?) und sollte somit sowieso überall und nicht nur im DAL verfügbar sein. Und wenn abhängig von deiner Einstellung(auf welche Datenbank zugegriffen wird) die GUI und sich ändert dann gibts dafür eine eigene GUI und wenn die andere Daten braucht dann bekommt diese eine eigene DAL Methode.

Ich halt viel von einem DAL der anhand eines Parameters irgendwelche anderen Daten zur Verfügung stellt. Auch bei der GUI denke ich das ein Trennen in zwei eigenständige Formulare sinnvoller ist.

Lg XXX

185 Beiträge seit 2007
vor 13 Jahren

Nein, es ist schon eine Suppe (Webapplikation auf ASP.NET AJAX-Basis in Kombi. mit jQuery), GUI splitten brauche ich nicht mehr, das habe ich schon durch die Separierung in UserControls erzielt.

Aber dein Einwand bzgl. Applikationseinstellung ist vermutlich vollkommen richtig, nur muss ich es trotzdem nach unten hin verarbeiten können. Das hab ich jetzt wie gesagt mit integern auf DAL-Ebene gelöst und es funktioniert jetzt auch soweit, habe meine 38 Fehlermeldungen abgearbeitet. ^^

Vielen Dank.