Announcement

Collapse
No announcement yet.

Providerunabhängig auf Datenbanken zugreifen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Providerunabhängig auf Datenbanken zugreifen

    Hallo

    ich muß mit einer Anwendung auf unterschiedlichste Datenbanken zugreifen.
    Leider gibt es für jede Datenbank auch je einen .NetDataProvider.
    Zum Einstieg habe ich den OleDbDataAdapter für den Zugriff verwendet. Ich dachte ich könnte mit der Ole-Geschichte und den Odbc-Datenquellen eine einfache Möglichkeit zur Verfügung stellen die Datenquelle umzustellen.
    Das functioniert mit MSSQL, Access und Oracle. Versuche mit PostgreSQL scheiterten daran, dass es dafür keinen OleDbDataAdapter-passenden Ole-Treiber gibt (oder ich den Treiber nicht kenne).
    Es gibt dafür wieder einen eigenen Odbc-Adapter von Microsoft (Microsoft.Data.Odbc.OdbcDataAdapter).
    Die nächste DB wird wohl der SQL-Server für die PDA's sein, der wiederum einen eigenen Adapter verwendet. ...

    Also die Frage:
    gibt es denn keine allgemein gültigen Zugriffe auf Datenbanken, wie es mit z.B. Delphi und der BDE möglich ist, indem eine Zentrale Umstellung den Zugriff umschaltet.

    In der Zeitschrift dot.net 05.02 fand ich einen interessanten Artikel dazu (.NetDataProvider). Leider wird dort direkt mit dem DataReader gearbeitet. Bis jetzt ist es mir nicht gelungen das ganze auf die DataAdapter zu übertragen. Es scheitert eigentlich bei allen Versuchen an der Update-Methode des DataAdapter. Die kann eine geänderte Zeile nicht updaten oder irgendwelche Adaptertypen passen nicht zusammen, verzweifel, verzweifel, verzweifel...
    Aber gerade die Update-Methode ist genial und wird auch massiv genutzt.

    Vielleicht kennt jemand eine Möglichkeit so etwas zu realisieren.

    Schon mal Danke

  • #2
    Hallo,

    >..gibt es denn keine allgemein gültigen Zugriffe auf Datenbanken...

    in den letzten Jahren hat Microsoft über das Gespann OLE DB + ADO ( = MDAC) versucht, einen universellen Zugriffsweg anzubieten. Aber wie die Erfahrungen im "praktischen Feldversuch" gezeigt haben, hat das aus verschiedenen Gründen nicht funktioniert. Als Beispiel möchte ich hier nur das Recordset-Objekt von ADO nennen, das über verschiedene Parameter in grundsätzlich unterschiedliche Betriebsarten (Server-Modus, Client-Modus, getrennter Modus) geschaltet werden konnte. Anscheindend war sowohl der durchschnittliche Entwickler mit diesem Entscheidungsspielraum überfordert (d.h. um die richtige Entscheidung treffen zu könnte, muss sich der Entwickler tief in die Internas des Recordset-Objekts einarbeiten, was viele aus Zeitgründen nicht machen konnten) als auch die Nebenwirkungen des Prinzip des "kleinsten gemeinsamen Nenners" doch höher als Anfangs vermutet.

    Mit ADO.NET hat Microsoft diesen universellen Ansatz verlassen und greift sowohl was die Objekte als auch die verschiedenen Datenbanken angeht nur noch zu "Spezialisten". Das "Know-How" steckt nun in dem Klassengenerator für die typisierten DataSets (und somit im DataAdapter), denn spätestens an dieser Stelle müssen die Eigenheiten der verwendeten Datenbank berücksichtigt werden. Denn letztendlich sind auch die Datenbanken funktional nicht gleichwertig - und die vom Kunden mit dem Kauf eines Produkts bezahlte Funktionalität kann man nur dann richtig ausnutzen, wenn der Treiberweg diesem Produk auf den Leib geschrieben wurde.

    Um auf die Frage zurückzukommen, der einzige halbwegs passende Weg führt über den <i>ODBC .NET Data Provider</i> und der Kombination von OdbcDataReader- und OdbcCommand-Objekten. Wenn auf die Bequemlichkeiten des DataAdapters verzichtet wird und sich das Programm nur auf die SQL-Anweisungen beschränkt, die von allen in Frage kommenden Datenbanken unterstützt werden, ist dieser Weg universell für Datenbanken jeglicher Art (von dBASE bis zu DB2) geeignet.

    P.S: Auch Borland hat vom universellen Weg (BDE) Abstand genommen und beschränkt sich beim angedachten Nachfolger dbExpress (alias <i>BDP.NET</i> für die eigenen .NET-Entwicklungsumgebungen <i>C# Builder</i> und <i>Delphi for .NET</i>) nur auf eine Handvoll SQL-Datenbanken - wobei aber dort getreu dem Prinzip des "kleinsten gemeinsamen Nenners" spezielle Besonderheiten dann nicht zur Verfügung stehen

    Comment


    • #3
      Schönen Dank

      &gt;.. P.S: Auch Borland hat vom universellen Weg (BDE) Abstand genommen...
      Leider! Für viele Anwendungen ist die BDE und deren Funktionsumfang aber vollkommen ausreichend. Ok nicht unbedingst die schnellste Art, aber sehr flexibel. Der Große Vorteil leigt darin, <b>nicht</b> unbedingt Eine Anpassung auf eine andere DB durchführen zu müssen. Der eingeschlagene Weg, alles zu Spezialisieren, führt dazu, dass <b>immer</b> irgend eine Anpassung notwendig ist! --> für viele kleinere Anwendungen unverhältnismäßig großer Aufwand! Wirklich gut finde ich daran, dass in den meisten Fällen eine leichte Anpassung der SQL's schon ausreicht. Bei den .NetDataProvidern muß man sogar die Zugriffskomponenten austauschen!
      Aber es soll nicht sein. OK.

      Eine weitere Frage:
      Ich habe versucht eine Klasse dazu zu erstellen. Diese bildet den benötigten Funktionsumfang für einen universellen Zugriff ab. Leider scheitere ich immer wieder am Update einer Zeile. Das Problem liegt beim Anlegen der Parameter für das UpdateCommand. Wie kann ich aus einer geänderten Tabelle die ursprünglichen Werte einer geänderten Zeile für die where - Parameter entnehmen? Ich bekomme immer nur die neuen! Dadurch findet das Update die zu ändernde Zeile in der DB nicht und nix passiert!

      &gt;..Um auf die Frage zurückzukommen, der einzige halbwegs passende Weg führt über den ODBC .NET Data Provider...

      Ich werde inzwischen mal mit dem ODBC-Provider versuchen das Problem in den Griff zu bekommen.

      Vielen Dan

      Comment


      • #4
        Hallo,

        &gt;Wie kann ich aus einer geänderten Tabelle die ursprünglichen Werte einer geänderten Zeile ...?

        Damit das DataSet später beim Abgleich mit der originalen Datenbanktabelle die zusammengehörenden Datensätze finden kann, speichert das DataSet gleich mehrere Sichtweise auf jedes Feld der Datenmenge:

        1. <b>DataRowVersion.Current</b> enthält den aktuellen Wert des Feldes

        2. <b>DataRowVersion.Original</b> enthält den originalen Wert des Feldes, der aus der Datenbank kopiert wurde

        Comment


        • #5
          Vielen Dank

          Aber ich habe jetzt das Problem, die Parameter zu dem Updatecommand anlegen zu müssen. Dabei benötige ich die Typen und vor allem die Größe der Felder. Gibt es denn eine Möglichkeit die Größe festzustellen (z.B. für Felder: VARCHAR(<B>50</B>))? Ich habe es mit <B>aktSize = aktrow.Table.Columns[aktfield].MaxLength;</B> versucht. Hat immer -1 zurückgeliefert!
          Oder gibt es vielleicht eine andere Methode die Updateparameter (zur Findung des ursprünglichen Datensatzes) anzulegen, ohne all diese Daten übergeben zu müssen????? Es müsste doch reichen, auf die DataRowVersion.Current zu verweisen?

          (...Das ist ein Fass ohne Boden... ich komm nicht weiter ...

          Comment


          • #6
            Hallo,

            im Fall des SqlCommandBuilder steht die Methode <b>DeriveParameters</b> zur Verfügung, um sich <b>SqlDbType</b> und <b>Size</b> aufzählen zu lassen.

            &gt;Es müsste doch reichen....

            Nun, man könnte generell Alles als Zeichenkette verpackt über eigene Command-Objektinstanzen abschicken, in diesem Fall sind die Parameter außen vor

            Comment


            • #7
              Nochmals Danke

              Wie man sieht hänge ich immer noch an dem Problem. Und eine akzeptable Lösung dazu habe ich noch nicht gefunden. Außer der Update-Methode funktioniert alles wunderbar! Aber genau die ist nicht zu umgehen. Ich werde nicht aufgeben...

              &gt;Alles als Zeichenkette verpackt ...

              Nun das scheitert wieder an Blob-Feldern. Oder

              Comment

              Working...
              X