Paradigmenwechsel mit ADO.NET

Veröffentlicht: 09. Dez 2001 | Aktualisiert: 18. Jun 2004

Von Ralf Westphal

Unter dem Begriff ADO.NET fasst der .NET Framework die Klassen für den Daten(bank)zugriff zusammen. Anders als der Name ADO.NET jedoch suggerieren mag, weicht diese Klassenbibliothek in mancherlei Hinsicht stark von ihren COM-basierten Vorgängerversionen ADO 2.x ab. Änderungen in der Benennung von Klassen oder Methoden sind dabei allerdings vergleichsweise unbedeutend. Entscheidend ist, dass ADO.NET mit dem vorherrschenden ISAM- oder C/S-orientierten Umgang mit Datenbanken bricht. An seine Stelle treten Datencaches und Datenzugriffe größerer Granularität.

Auf dieser Seite

 MSDN Kolumne Juni 2001
 Bisherige Datenzugriffsmethoden
 Kritik bisheriger Datenzugriffsmethoden
 Datenzugriffsmethoden bei ADO.NET
 Fazit

MSDN Kolumne Juni 2001

Bild01

ADO.NET stellt sicherlich eine Weiterentwicklung, eine Evolution von ADO 2.x dar. Gleichwohl revolutioniert ADO.NET den Umgang mit Datenbanken bzw. den Umgang mit Daten unterschiedlicher Quellen. Nachfolgend möchte ich die wichtigsten Aspekte dieser "Revolution" beschreiben - allgemeine Einführungen in ADO.NET finden Sie an anderer Stelle (s. [DinoEsp] und [RobMac]).

 

Bisherige Datenzugriffsmethoden

Bei einer Revolution geht es immer um eine radikale Abkehr vom Bisherigen. Wenn wir also die ADO.NET-Revolution begutachten wollen, dann sollten wir uns zumindest kurz vergegenwärtigen, welches Datenzugriffsparadigma bisher en vogue war. Dabei ist es tatsächlich recht unerheblich, ob Sie in Ihren Projekten eher DAO, RDO oder ADO eingesetzt haben.

ISAM-basierter Datenzugriff
All diese Datenzugriff-APIs sind in dieser Hinsicht sehr ähnlich. Sie haben als eine gemeinsame Wurzel den ISAM-basierten Zugriff auf Daten, d.h. einen Zugriff, bei dem sehr stark Tabellen mit ihren Indizes im Vordergrund stehen und meist einzelne Sätze direkt durch Angabe eines Schlüssels angefahren werden. Zur Erläuterung ein wenig Pseudocode:

tb = Database.OpenTable("myTable") 
tb.SelectIndex "ID" 
tb.Seek "1234" 
tb.Lock 
tb.Field("Name") = "Peter Muster" 
. 
tb.Update 
tb.Unlock

Symptomatisch für die ISAM-Programmierung sind:

  • Direkter Umgang mit Tabellen

  • Direkter Zugriff auf einzelne Sätze in Tabellen über Schlüssel

  • Direktes Sperren einzelner Sätze

ISAM-Programmierung findet auf einer sehr niedrigen Abstraktionsstufe statt. Operationen zur Untermengenbildung oder Satzsperrung müssen explizit codiert werden. Der Gewinn: Hohe Geschwindigkeit in Szenarien, bei denen häufig direkte Zugriffe auf einzelne Sätze nötig sind.

SQL-basierter Datenzugriff
Eine zweite gemeinsame Wurzel der genannten APIs ist SQL. Für die Betrachtungen hier sind allerdings nur die DML (Data Manipulation Language: insert, update, delete) und die SQL Select-Anweisung interessant.

Im Gegensatz zur ISAM-Programmierung sind SQL-Anweisungen mengenorientiert. Sie beziehen sich auf u.U. sehr große Grundmengen von Datensätzen in Tabellen und selektieren/manipulieren darin Untermengen (die sozusagen als Sonderfall auch nur einen Datensatz enthalten können). Während ISAM-Anweisungen genau beschreiben wie eine Selektion/Manipulation durchzuführen ist, geben SQL-Anweisungen an, welches Endergebnis erwartet wird.

Der obige ISAM-Pseudocode ließe sich in einer einzigen SQL-Anweisung ausdrücken:

update myTable set Name = "Peter Muster" where id="1234"

Um Indizes, Sperrungen o.ä. müssen Sie sich bei SQL-Anweisungen im Grunde nicht kümmern. Der Gewinn liegt in einer Konzentration auf das gewünschte Ergebnis, einer hohen Geschwindigkeit bei Mengenoperationen und einer Möglichkeit zur Zentralisierung von Operationen in einem Server-Prozess.

Die ersten beiden Vorteile realisieren alle relationalen Datenbanksysteme, auf die Sie mit SQL zugreifen können, seien es MS Access oder SQL Server oder Oracle.

Der letzte Vorteil ist jedoch "echten" Datenbankservern wie SQL Server oder DB2 vorbehalten. Sie führen die Untermengenbehandlung zentral auf einem Rechner (Server) durch und übertragen zu den auftraggebenenden Arbeitsplätzen (Client) lediglich die Resultate. Das verringert den Verkehr in einem Netzwerk erheblich und steigert damit den Durchsatz. MS Access ist hingegen immer noch der ISAM-Welt verhaftet, da auch trotz SQL letztlich alle Operationen auf den Client-Rechner stattfinden, selbst wenn die Datenbank auf einem zentralen Fileserver liegt.

Die Vorteile von Mengenorientierung und Abfrage-/Manipulationssprache erkauft SQL damit, dass es Ihnen eigentlich keinen direkten Zugriff auf Datensätze gibt. Sie beschreiben lediglich die Sätze, mit denen etwas getan werden soll - tun es aber nicht selbst. Das ist auch der Grund, warum frühere SQL-Engines wie Ocelot das Ergebnis einer Select-Abfrage ausschließlich in Form einer CSV-Zeichenkette zurücklieferten (je Zeile 1 Datensatz in dem die Felder durch einen Delimiter von einander getrennt sind). Die Daten darin waren Schnappschüsse der Daten in der Datenbank und hatten mit dieser keine Verbindung; eine direkte Veränderung von Sätzen war nicht möglich - und nicht erwünscht.

Cursor-basierter Datenzugriff
DAO, RDO und ADO haben ihren Wurzeln eine weitere Möglichkeit zum Datenzugriff hinzugefügt. Sie haben sozusagen die ISAM-orientierte Datenmanipulation auf Untermengen von Tabelleninhalten ausgedehnt. Ein ADO-Beispiel:

Dim rs as New Recordset 
rs.cursorlocation = adUseServer 
rs.Open "select name from myTable where id='1234'", ".", adOpenKeyset, . 
rs!name = "Peter Muster" 
rs.update

Dabei steht eine neue Datenstruktur im Mittelpunkt: der Cursor. Er stellt eine Verbindung zu einer Datenbank dar, über die Sätze in durch select ausgewählten Untermengen von Tabelleninhalten unmittelbar verändert werden können. Es ist kein Rückgriff auf DML-Anweisungen nötig.

Cursor vereinigen die Vorteile der ISAM-Programmierung (direkte Manipulation, Datenstruktur für Mengen von Sätzen) mit denen von SQL (Mengenoperationen, insbesondere bei der Auswahl von Datensätzen). Sie kapseln sozusagen die oben erwähnte CSV-Resultatsmenge und die DML-Operationen zu ihrer Änderung in einer Datenstruktur, die eine freie Bewegung über die Menge (Scrollen) und ihre unmittelbare Manipulation ermöglicht.

Traditionell sind diese Cursor sog. serverseitige Cursor. Das heißt, sie stehen in ständiger Verbindung zur Datenquelle, laden während des Scrollens Daten von dort nach und schreiben Änderungen sofort zurück.

Ausnahmen bilden lediglich zwei Cursortypen:

  • Der alte Snapshot-Cursor enthält eine vollständige, read-only Kopie aller ausgewählten Daten und kann auf Nachladen und damit auf eine Verbindung zur Datenbank nach der Selektion verzichten.

  • Der neue, mit ADO eingeführte clientseitige Cursor für unverbundene Recordset-Objekte entspricht einem Snapshot, lässt die Änderung von Daten jedoch zu. Alle Manipulationen können später en bloc durch die UpdateBatch-Methode persistiert werden.

Der Gewinn von Cursorn ist offensichtlich: Sie vereinen Einfachheit (in der Selektion) mit Unmittelbarheit (in der Manipulation). Dem entgegen stehen jedoch einige Nachteile.

 

Kritik bisheriger Datenzugriffsmethoden

Keine Technologie kann ohne Tradeoffs eingesetzt werden. Allerdings muss man immer fragen, ob und wie ihre Nachteile im angestrebten Einsatzumfeld relevant sind.

Der ISAM-orientierte Datenzugriff z.B. ist aufwändig zu programmieren ("Zusammensetzen" von komplexeren Abfragen, explizites Locking) und bietet sich weniger für Anwendungen in einem Netzwerk an, da Daten nur auf den Client-Rechnern ausgewertet werden. Die Netzwerklast ist dadurch hoch. Wo es allerdings nicht um Netzwerkanwendungen geht, sondern um hohe Geschwindigkeit beim Zugriff auf einzelne Sätze, ist ein ISAM-Datenzugriff natürlich ein probates Mittel.

Solange wir uns also der Vor- und Nachteile von Datenzugriffstechnologien bewusst sind und ihren Einsatz auf unkritische Bereiche beschränken, d.h. Tradeoffs weitgehend vermeiden, ist die Welt in Ordnung. Für reinen ISAM- und reinen SQL-Datenzugriff fällt das leicht. Bibliotheken, die sie "pur" implementieren, sind aber zumindest in Geschäftsanwendungen kaum im Einsatz. Microsofts APIs haben proprietäre Lösungen anderer Hersteller weitgehend verdrängt. Der Wunsch nach Standardisierung, Datenquellentransparenz und mehr Features waren die Triebfedern.

Knifflig ist daher vor allem der Einsatz von "hybriden" APIs wie DAO, RDO, ADO, die mit einem Bein in der ISAM-Welt und mit dem anderen in der SQL-Welt stehen. Ihre Cursorvielfalt ist dafür u.a. deutlicher Ausdruck. Durch die Kombination von Cursorn und SQL suggerieren sie, dass die Programmierung von Datenbankanwendungen in Netzwerken genauso unmittelbar sein könnte, wie die von Single-User-Applikationen.

Als Entwickler verknüpfen wir schnell und gerne ein SQL Select mit einem serverseitigen Cursor, um Datenbankinhalte zu traversieren und gleichzeitig zu ändern. Das ist verständlich. Das ist auch intuitiv. Das ist jedoch nur bis zu einem gewissen Grad ohne Nachteile. Sie machen sich umso mehr bemerkbar, je ausgiebiger wir das ISAM-Erbe der APIs benutzen:

  • Über lange Zeit offene, mit der Datenbank verbundene Cursor belasten die Ressourcen des Datenbankrechners. Das ist unkritisch, solange nur wenige Verbindungen/Cursor offen sind und macht sich daher in vielen kleinen und mittleren Anwendungen nicht nachteilig bemerkbar - kann aber zu einem Problem werden, wenn diese Anwendungen wachsen.

  • Cursor, die beim Traversieren immer wieder Daten nachladen, belasten die Verbindung zwischen Client und Datenbankrechner. Das gilt natürlich insbesondere für Fileserver-Datenbanksysteme wie MS Access, aber auch für "echte" Datenbankserver.

  • Feingranulare Änderungen an Cursorn, die ständig an die Datenbank geschickt werden, belasten die Verbindung zwischen Client und Datenbankrechner. Bei Installation von Datenbank und Anwendung auf dem selben Rechner ist das unkritisch, nicht so jedoch in Netzwerken.

  • Das oft im besten Glauben eingesetzte explizite pessimistische Sperren von zu verändernden Datensätzen - insbesondere, wenn Sperren über sehr lange Zeit gehalten werden - behindert Datenbanksysteme bei ihren Mengenoperationen. Insert, Delete und Update benutzen Satzsperren, um Transaktionssicherheit sicherzustellen. Dabei ist es am besten, wenn das Datenbanksystem solche Sperren nach eigenem Ermessen setzen/lösen kann. Explizite Locks durch Anwendungen stehen dem entgegen.

Als Kritik an den bisherigen Datenzugriffstechnologien ergibt sich damit, dass sie zwar sehr vorteilhaft zwei Welten (ISAM & SQL) verbinden - aber auf der anderen Seite keinen formalen Unterschied machen in der Bedienung so unterschiedlicher Szenarien wie Single-User- und Netzwerk-Datenbankanwendung. Denn sehr unterschiedlich sind diese Szenarien, weil beim Einsatz in Netzwerken Aspekte wie Netzwerklast, Gleichzeitigkeit von Zugriffen und Ressourcenverbrauch auf dem Server zwingend berücksichtig werden müssen!

In Abwesenheit eines formalen Zwangs tendieren wir aber dahin, weniger zukunftsorientiert und mehr "bequem" zu denken. Auch typische Client/Server (C/S) Datenbank-Anwendungen, die durchaus mit Sensibilität gegenüber Ressourcen, Last und steigender Benutzerzahl entwickelt werden, machen starken Gebrauch von Cursorn trotz der angesprochenen Nachteile, weil sie so "bequem" zu programmieren sind. Bei kleinen Applikationen ist das noch viel mehr der Fall. Dort findet sich u.U. selbst mit DAO noch "echte" ISAM-Programmierung.

In Maßen und am richtigen Ort eingesetzt, ist das natürlich kein Problem. Die häufige Durchdringung von Datenzugriffscode mit serverseitigen Cursorn macht es allerdings schwer, Anwendungen bei steigender Benuzterzahl skalierbar zu halten: Das betrifft sowohl den Datendurchsatz im Netzwerk, wie auch den Ressourcenverbrauch auf dem Datenbankserver und die Verwaltung von Sperren. Auf den Punkt gebracht lässt sich vielleicht formulieren: Der explizite Eingriff in Datenbankdaten mit Cursorn steht automatischen Optimierungen durch das Datenbanksystem entgegen. Wir bezahlen den Kontrollgewinn also oft teuer.

 

Datenzugriffsmethoden bei ADO.NET

ADO.NET ist ein Kind seiner Zeit - wie auch die vorherigen APIs. Sie stehen vor allem in der Tradition des Wunsches nach unmittelbarer Kontrolle bei maximaler Bequemlichkeit in vergleichsweise überschaubaren Szenarien bei gegebenem Programmierparadigma:

  • Überschaubar waren bisher die meisten Szenarien, weil sich die Benutzeranzahl einer Anwendung relativ gut bestimmen ließ. Sie war abhängig von einer "abzählbaren, relativ schwach wachsenden Menge" von Anwendern in einemUnternehmen.

  • Und das Programmierparadigma war das zustandsbehafteter Anwendungen: Datenbankverbindungen konnten zwischen den "abzählbar vielen" Clients und dem Server ständig offen gehalten werden.

Seit diesen Zeiten der bisherigen APIs hat sich die Softwarewelt jedoch weiter gedreht. Die bisherigen Grundannahmen gelten immer weniger.

  • Überschaubarkeit geht in einer Welt, in der sich potenziell jede Anwendung früher oder später dem Internet öffnen können soll, verloren. Die Zahl der morgigen Anwender kann schnell um Zehnerpotenzen größer sein als die der heutigen.

  • Und das Programmierparadigma verliert seine Zustandsbehaftetheit, weil ein Zugriff auf Methoden/Daten über das Internet (vgl. SOAP) zustandslos sein muss aufgrund des HTTP-Protokolls, welches für große Benutzerzahlen ausgelegt ist. Nur mit dieser Zustandslosigkeit lässt sich der Ressourcenverbrauch von Servern in den Griff bekommen.

Angesichts einer durch das Internet auf uns gekommenen Veränderung an bisher kaum hinterfragten Grundannahmen, setzt ADO.NET sich nun von seinen "Vorfahren" ab. ADO.NET reagiert auf die Veränderungen - und versucht gleichzeitig, das Beste aus "der alten Welt" zu retten.

An dieser Stelle möchte ich nicht auf die Veränderungen im Kleinen bei ADO.NET eingehen. Managed provider oder die allgemeine Klassenhierarchie von ADO.NET werden an anderer Stelle ausführlich erklärt. Auch dass ADO.NET selbstverständlich SQL unterstützt ist an dieser Stelle nicht entscheidend. Die Revolution von ADO.NET liegt vielmehr in seiner Haltung gegenüber Cursorn.

Serverseitige Cursor
ADO.NET unterstützt (zumindest in der .NET Framework Beta 1) nur noch einen serverseitigen Cursor: einen read-only, forward-only Cursor, den sog. firehose Cursor. Er dient der schnellstmöglichen Traversierung von Datensatzmengen, die Sie per SQL Select auswählen.

Diese Art eines serverseitigen Cursor ist relativ unkritisch im Hinblick auf die oben genannten Nachteile: Als read-only Cursor stellt er keine Anforderungen an Satzsperren und als forward-only Cursor sind Ressourcenverbrauch wie Netzwerklast kleinstmöglich.

Weitere serverseitige Cursor, insbesondere veränderbare, gibt es nicht. Dynasets und Keysets gehören der Vergangenheit an.

Doch wie sollen dann Manipulationen an Daten durchgeführt werden?

Die Revolution: Daten cachen
Datenmanipulationen sollen Sie natürlich vor allem über SQL-Anweisungen (Insert etc.) und Stored Procedures vornehmen. Wo dies aber zu unhandlich ist, können Sie weiterhin Cursor benutzen. Allerdings ausschließlich unverbundene Cursor.

ADO.NET erhebt damit den Sonderfall des ADO 2.x Recorset mit clientseitigem updatebatch-Cursor zur Norm. In sog. DataSet-Objekten können Sie beliebig viele Datensatzmengen (sozusagen mehrere Recordset-Objekte) zusammenfassen und sogar über Relationen miteinander verbinden. Ein DataSet-Objekt wird damit zur in-memory Datenbank, die einen Ausschnitt aus einer (oder mehreren) Datenquellen verwaltet. In einem DataSet cachen Sie demnach Teile Ihrer Daten mehr oder weniger lange. Das ist die ADO.NET Revolution!

Veränderungen an den Daten in einem DataSet persistiert ADO.NET nicht sofort.Vielmehr bestimmen Sie den Zeitpunkt, wann Sie aufgelaufene Änderungen an eine Datenbank übertragen. En bloc und unter Einsatz vom DML bzw. Stored Procedures persistiert ADO.NET dann die Modifikationen.

Was ist der Gewinn dieses Vorgehens? Für die Datenbeschaffung und Modifikation benutzt ADO.NET SQL-Datenzugriffe, für die Datenhaltung und Traversierung Datenkopien in unverbundenen Cursorn. ADO.NET reduziert damit Netzwerklast sowie Ressourcenverbrauch erheblich und gestattet auch keinen Eingriff mehr in die Sperrung von Sätzen.

ADO.NET trägt damit einer veränderten Welt Rechnung, in der Mehrbenutzeranwendungen die Regel sind und Skalierbarkeit wie auch die Entkopplung von Komponenten generelle Tugenden.

Welche Veränderungen in der Denk-/Arbeitsweise bringt das mit sich?

Datensätze logisch sperren
Datensätze in Cursorn, die nicht mit der Datenquelle verbunden sind, können wir nicht direkt sperren. Ein pessimistisches Locking ist unter ADO.NET also nicht möglich.

Aber was wie ein Verlust aussieht, ist in Wirklichkeit ein Gewinn:

  • Bisherige Mittel zur Sperrung von Datensätzen haben oft mehr geschadet als genützt - insbesondere in C/S-Anwendungen, bei denen ein Datenbankserver dadurch in seinem automatischen Lock-Management "behindert" wurde.
    Deutlich wird die Fehleinschätzung von Verwendung und Nutzen eigenhändiger Satzsperren an der früheren Forderung nach row level locking z.B. in MS Access. Ohne Frage ist ein so feingranulares Locking von Vorteil für die Transaktionsverarbeitung - aber es wurde vielfach aus anderen Gründen gefordert: um einzelne Sätze über längere Zeit von Hand zu sperren. Das aber ist kontraproduktiv.

  • ADO.NET zwingt uns in ein gewisses, heutigen Anwendungen angemessenes Korsett. Architektur und Anforderungen von Mehrbenutzeranwendungen werden durch einen formalen "Zwang" unterstützt. Optionsvielfalt bei der Auswahl des besten ADO Cursortyps weicht einer Beschränkung, innerhalb derer sich Kreativität entfalten kann.

Darüber hinaus implementiert ADO.NET selbst optimistisches Locking beim Speichern von DataSet-Änderungen en bloc.

Andere Sperren zu realisieren, ist uns überlassen. Sie gelten nur innerhalb der Businesslogik einer Anwendung; eine Datenbank-Engine hat von ihnen keine Kenntnis und ist damit auch nicht in der Verwaltung ihrer physikalischen Locks beeinträchtigt.

Das ist durchaus positiv zu sehen, da wir somit frei sind, Zeitpunkt und Granularität solcher logischen Sperren unabhängig von einem Datenbanksystem zu bestimmen. Wichtig ist hierbei vor allem, dass keine Datenmanipulationen an diesen Sperren vorbei mehr möglich sein dürfen. ADO.NET fördert insofern auch die Kapselung von Businesslogik in Komponenten, um diese Bedingung zu erfüllen.

Auf der anderen Seite wäre es aber natürlich bequem, würde ADO.NET in dieser Hinsicht helfen. Doch Microsoft hat bzgl. "logischer" Sperren noch keinen Technologievorschlag gemacht.

In Dokumenten denken
Die zweite notwendige Veränderung in unserer Denkweise ist eine Bewegung hin zur Arbeit mit Daten größerer Granularität. ADO Recordset-Objekte legen uns nahe, in Tabellen und einzelnen Sätzen zu denken. Beziehungen zwischen Tabellen werden über Joins abgebildet. In bisheriger Ermangelung anderer Datenstrukturen als tabellarischer Cursor haben wir kaum anders denken können. Aber war dies ein "natürliches" Denken? Eines, das dem persistenten oder in-memory Datenmodell angemessen war? Eher nicht.

Natürlicher wäre es gewesen, hätten wir beim Datenzugriff einfach Zusammengehöriges zusammenhalten und entsprechend seinen Beziehungen abbilden können. Ein Beispiel: Rechnungen und ihre Positionen gehören eng zusammen und stehen in einer hierarchischen 1:n Beziehung. Warum können wir sie dann nicht auch als Einheit und Hierarchie behandeln? Stattdessen lösen wir die Beziehung auf und begnügen uns mit einer "neuen Tabelle", die in jeder Zeile den Rechnungskopf wiederholt.

Shaped Recordset-Objekte haben spät in ADO versucht, diese unnatürliche Abbildung zu vermeiden - allerdings aus verschiedenen Gründen nur mit begrenztem Erfolg. Doch der Ansatz war begrüßenswert.

ADO.NET nimmt diesen Gedanken mit dem DataSet auf. Ein DataSet ist geradezu dafür prädestiniert, Daten aus verschiedenen, in Beziehung stehenden Tabellen (auch unterschiedlicher Datenquellen) zusammen zu fassen. So können Rechnungen und Positionen getrennt hineingeladen, mit einer Relation verknüpft und als Hierarchie traversiert werden. Zusammengehöriges bleibt im DataSet zusammen und in seiner natürlichen Beziehung.

Aber nicht nur das: DataSet-Objekte lassen sich auch serialisieren; sie sind somit die ideale Datenstruktur, um "Dokumente" zwischen Anwendungsschichten (z.B. serverseitigem Business API (BAPI) und clientseitigem Business Objektmodell (BOM)) zu transportieren. Als "Dokumente" kann man die in einem DataSet zusammengefassten Daten bezeichnen, z.B. eine Rechnung mit ihren Positionen oder eine Firma mit mehreren Adressen, die wiederum jeweils mehrere Ansprechpartner haben, zu denen u.U. viele Telefonnummern gehören.

Wenn Sie in dieser Weise Zusammengehöriges bündeln, können Sie einen zweifachen Gewinn realisieren:

  • Ihre Anwendung wird wartbarer/transparenter, weil Sie eine natürlichere Abbildung für Ihr persistentes Datenmodell wählen.

  • Sie sparen aufwändige Roundtrips zwischen Client (BOM) und Server (BAPI), da mit einem Aufruf größere Datenmengen ("Dokumente") übertragen werden.

ADO.NET unterstützt mit dem generischen Datencontainer DataSet ein objektorientiertes Denken, das sich mit relationalen Datenbanken verträgt. Diese Denkweise jedoch ist konträr zur bisherigen, die sich vom relationalen Modell, von Tabellen, Relationen, Joins hat leiten lassen.

Es wird also ein wenig dauern, bis der neue Ansatz Fuß fasst; am Ende ist es jedoch in vielen Bereichen intuitiver - und einer neuen Welt angemessener, die aus verteilten Anwendungen, heterogenen Datenbeständen und dem Zwang zu skalierbaren Anwendungen bestehen wird.

 

Fazit

Der Paradigmenwechsel von ADO.NET steckt in der zentralen Containerklasse DataSet. DataSet-Objekte fassen mehrere Datensatzmengen zusammen und können sie in Beziehung setzen. Vorhandene Hierarchien bleiben erhalten. Da einmal hineingeladene Daten nicht mehr mit ihren Quellen verbunden sind, können DataSet-Objekte als Cache oder in-memory Datenbank angesehen werden.

Der Umgang mit Daten in dieser Weise steht in starkem Kontrast zur bisherigen Cursor-Philosophie. Eingefahrene Strategien verlieren an Wert, neue müssen gefunden werden. In den meisten Fällen wird dies mit mittelfristigen Vorteilen möglich sein. Offenheit und Bereitschaft zum Umlernen sind dafür aber nötig. Damit verbunden ist auch ein Schritt in Richtung sauberer Entkopplung von Untersystemen. Er allein stellt einen Gewinn dar.

In wenigen Fällen allerdings mögen die Möglichkeiten bisheriger serverseitiger Cursor unverzichtbar bleiben. Solange ADO.NET hier keine weiteren Angebote macht, hilft dort nur der Rückgriff auf ADO 2.x via COM-Interop.

Referenzen
[DinoEsp] Dino Esposito, ADO.NET for the ADO Programmer, https://msdn.microsoft.com/library/techart/adonetdev.htm
[RobMac] Rob Macdonald, ADO.NET, http://www.dnjonline.com/articles/essentials/iss22\_essentials.html