Einführung in Datasets

Datasets speichern Daten in einem separaten Cache. Die Struktur eines Datasets kann mit der Struktur einer relationalen Datenbank verglichen werden: Damit wird ein hierarchisches Objektmodell von Tabellen, Zeilen und Spalten zur Verfügung gestellt. Darüber hinaus sind darin die für das Dataset definierten Einschränkungen und Beziehungen enthalten.

Hinweis   Verwenden Sie Datasets, wenn Sie mit einem Tabellen- und Zeilensatz arbeiten möchten, während Sie nicht mit der Datenquelle verbunden sind. Die Verwendung eines Datasets ist nicht immer die optimale Lösung zum Entwerfen des Datenzugriffs. Weitere Informationen finden Sie unter Empfehlungen zur Zugriffsstrategie auf Daten.

Sie können Datasets mit den folgenden Komponenten des .NET Framework-Namespaces erstellen und bearbeiten.

Dataset-Namespace

Die wichtigen Teile eines Datasets werden über Standardprogrammierkonstrukte wie Eigenschaften und Auflistungen bereitgestellt. Beispiel:

  • Die DataSet-Klasse enthält die Tables-Auflistung von Datentabellen und die Relations-Auflistung von DataRelation-Objekten.
  • Die DataTable-Klasse enthält die Rows-Auflistung von Tabellenzeilen, die Columns-Auflistung von Datenspalten und die ChildRelations-Auflistung und ParentRelations-Auflistung von Datenbeziehungen.
  • Die DataRow-Klasse enthält die RowState-Eigenschaft, deren Werte angeben, ob und wie die Zeile geändert wurde, seit die Datentabelle zum ersten Mal aus der Datenbank geladen wurde. Mögliche Werte für die RowState-Eigenschaft sind Deleted, Modified, New und Unchanged.

Datasets, Schemas und XML

Ein ADO.NET-Dataset ist eine Datenansicht (eine relationale Ansicht), die in XML dargestellt werden kann. In Visual Studio und .NET Framework werden alle Arten von Daten im XML-Format gespeichert und übertragen. Insofern gibt es eine enge Beziehung zwischen Datasets und XML. Diese Beziehung ermöglicht es Ihnen, folgende Dataset-Features zu nutzen.

  • Die Struktur eines Datasets, also seine Tabellen, Spalten, Beziehungen und Einschränkungen, können in einem XML-Schema definiert werden. XML-Schemas sind ein auf Standards basierendes Format des W3C (World Wide Web Consortium) zum Definieren der Struktur von XML-Daten. Datasets verwenden die Methoden ReadXmlSchema und WriteXmlSchema, um Schemas, die strukturierte Informationen speichern, zu lesen und zu schreiben. Wenn kein Schema verfügbar ist, kann das Dataset (über die InferXmlSchema-Methode) ein Schema aus den Daten in einem XML-Dokument ableiten, das eine relationale Struktur aufweist. Weitere Informationen zu Datasets und Schemas finden Sie unter Einführung in XML-Schemas.
  • Sie können eine Dataset-Klasse generieren, die Schemainformationen enthält, mit denen ihre Datenstrukturen (wie Tabellen und Spalten) als Klassenmember definiert werden. (Weitere Informationen finden Sie unter "Typisierte und nicht typisierte Datasets" unten.)
  • Sie können ein XML-Dokument oder einen XML-Stream mit der ReadXML-Methode des Datasets in das Dataset einlesen und ein Dataset mit Hilfe der WriteXML-Methode des Datasets als XML schreiben. Da XML ein Standardformat für den Datenaustausch zwischen verschiedenen Anwendungen ist, können Sie ein Dataset mit Daten im XML-Format laden, das von anderen Anwendungen gesendet wurde. Entsprechend kann ein Dataset seine Daten als XML-Stream oder XML-Dokument schreiben, damit sie mit anderen Anwendungen gemeinsam genutzt oder einfach in einem Standardformat gespeichert werden.
  • Sie können eine XML-Ansicht (ein XMLDataDocument-Objekt) vom Inhalt eines Datasets erstellen und die Daten anschließend mit einer relationalen Methode (über das Dataset) oder einer XML-Methode anzeigen und bearbeiten. Die beiden Ansichten werden automatisch synchronisiert, sobald Änderungen vorgenommen werden.

Typisierte und nicht typisierte Datasets

Datasets sind entweder typisiert oder nicht typisiert. Ein typisiertes Dataset ist ein Dataset, das zunächst aus der DataSet-Basisklasse abgeleitet wird. Anschließend werden die Informationen in einer XML-Schemadatei (.xsd) zum Erstellen einer neuen Klasse verwendet. Informationen aus dem Schema (Tabellen, Spalten usw.) werden generiert und in diese neue DataSet-Klasse als Gruppe von Objekten und Eigenschaften der ersten Klasse kompiliert.

Hinweis   Weitere Informationen zu Dataset-Schemas finden Sie unter XML-Schemas und Daten.

Da eine typisierte DataSet-Klasse von der DataSet-Basisklasse erbt, übernimmt die typisierte Klasse die gesamte Funktionalität der DataSet-Klasse und kann mit Methoden verwendet werden, die eine Instanz einer DataSet-Klasse als Parameter verwenden.

Ein nicht typisiertes Dataset besitzt dagegen kein entsprechendes integriertes Schema. Wie ein typisiertes Dataset enthält auch ein nicht typisiertes Dataset Tabellen, Spalten usw., die allerdings nur als Auflistungen zur Verfügung gestellt werden. (Wenn Sie die Tabellen und anderen Datenelemente in einem nicht typisierten Dataset manuell erstellen, können Sie die Struktur des Datasets mit der WriteXmlSchema-Methode des Datasets jedoch als Schema exportieren.)

Sie können beide Dataset-Arten in Ihren Anwendungen verwenden. In Visual Studio gibt es jedoch mehr Tools für typisierte Datasets, die die Programmierung von Datasets einfacher und weniger fehleranfällig machen.

Unterschiede beim Datenzugriff in typisierten und nicht typisierten Datasets

Die Klasse für ein typisiertes Dataset hat ein Objektmodell, in dem die Tabellen und Spalten zu Objekten der erster Klasse des Objektmodells werden. Wenn Sie mit einem typisierten Dataset arbeiten, können Sie mit folgendem Code auf eine Spalte verweisen. Beispiel:

' Visual Basic
' This accesses the CustomerID column in the first row of 
' the Customers table.
Dim s As String
s = dsCustomersOrders1.Customers(0).CustomerID

// C#
// This accesses the CustomerID column in the first row of 
// the Customers table.
string s;
s = dsCustomersOrders1.Customers[0].CustomerID;

Bei einem nicht typisierten Dataset verwenden Sie hingegen folgenden Code:

' Visual Basic
Dim s As String
s = CType(dsCustomersOrders1.Tables("Customers").Rows(0).Item("CustomerID"), String)

// C#
string s = (string) dsCustomersOrders1.Tables["Customers"].Rows[0]["CustomerID"];

Der Zugriff für typisierte Datasets ist nicht nur einfacher zu lesen, sondern wird auch vollständig von IntelliSense im Code-Editor von Visual Studio unterstützt. Mit der Syntax für typisierte Datasets lässt es sich nicht nur einfacher arbeiten, sie gewährleistet auch die Typüberprüfung beim Kompilieren und reduziert dadurch erheblich die Fehlerquote beim Zuweisen von Werten zu Dataset-Membern. Der Zugriff auf Tabellen und Spalten ist bei einem typisierten Dataset zur Laufzeit ebenfalls etwas schneller, da der Zugriff während des Kompilierens und nicht über Auflistungen zur Laufzeit bestimmt wird.

Typisierte Datasets bieten zwar viele Vorteile, in bestimmten Situationen sind nicht typisierte Datasets allerdings besser geeignet. Dies ist eindeutig der Fall, wenn kein Schema für das Dataset vorhanden ist. Dies kann beispielsweise vorkommen, wenn die Anwendung mit einer Komponente interagiert, die ein Dataset zurückgibt, dessen Struktur Sie aber nicht im Voraus kennen. Es kann auch vorkommen, dass Sie mit Daten arbeiten, die keine statische, vorhersagbare Struktur aufweisen. In diesem Fall ist es unpraktisch, ein typisiertes Dataset zu verwenden, da Sie die Klasse des typisierten Datasets mit jeder Änderung in der Datenstruktur neu generieren müssten.

Häufig werden Sie ein Dataset dynamisch erstellen müssen, ohne dafür ein verfügbares Schema zu haben. In diesem Fall bietet das Dataset einfach eine praktische Struktur zum Speichern von Informationen, so lange die Daten relational dargestellt werden können. Gleichzeitig profitieren Sie von den Funktionen des Datasets, etwa der Möglichkeit, Informationen zu serialisieren, die an einen anderen Prozess weitergeleitet werden müssen, oder eine XML-Datei zu schreiben.

Berücksichtigung der Groß- und Kleinschreibung bei Datasets

In einem Dataset muss die Groß- und Kleinschreibung bei Namen von Tabellen und Spalten standardmäßig nicht berücksichtigt werden, d. h. auf eine Tabelle im Dataset mit dem Namen "Customers" kann auch mit "customers" verwiesen werden. Dies entspricht den Benennungskonventionen in vielen Datenbanken wie SQL Server, wonach die Namen von Datenelementen nicht ausschließlich anhand der Groß- und Kleinschreibung unterschieden werden können.

Hinweis   Im Gegensatz zu Datasets spielt die Groß- und Kleinschreibung bei XML-Dokumenten eine Rolle, d. h. bei den Namen der in Schemas definierten Datenelemente muss die Groß- und Kleinschreibung berücksichtigt werden. In einem Schemaprotokoll kann beispielsweise ein Schema mit einer Tabelle "Customers" und einer weiteren Tabelle "customers" enthalten sein. Dies kann zu Namenskonflikten führen, wenn ein Schema zum Generieren einer Dataset-Klasse verwendet wird. Weitere Informationen finden Sie unter XML-Elemente, -Attribute und -Typen.

Die Groß- bzw. Kleinschreibung kann sich jedoch auf die Interpretation von Daten im Dataset auswirken. Wenn Sie beispielweise die Daten in einer Dataset-Tabelle filtern, werden mit den Suchkriterien unter Umständen unterschiedliche Ergebnisse zurückgegeben, abhängig davon, ob für den Vergleich die Groß- und Kleinschreibung berücksichtigt wird oder nicht. Mit der CaseSensitive-Eigenschaft eines Datasets steuern Sie, inwieweit die Groß- und Kleinschreibung beim Filtern, Suchen und Sortieren berücksichtigt werden soll. Alle Tabellen im Dataset erben standardmäßig den Wert dieser Eigenschaft. (Sie können diese Eigenschaft für jede Tabelle überschreiben.)

Füllen von Datasets

Ein Dataset ist ein Container, d. h. Sie müssen es mit Daten füllen. Wenn Sie ein Dataset mit Daten füllen, werden verschiedene Ereignisse ausgelöst, die Einschränkungsüberprüfung wird angewendet usw. Weitere Informationen über Aktualisierungen in einem Dataset und Aktualisierungen allgemein finden Sie unter Dataset-Aktualisierungen in Visual Studio .NET.

Es gibt verschiedene Möglichkeiten, ein Dataset zu füllen:

  • Rufen Sie die Fill-Methode eines Datenadapters auf. Dies führt dazu, dass der Adapter eine SQL-Anweisung oder eine gespeicherte Prozedur ausführt. Die Ergebnisse werden in eine Tabelle im Dataset übernommen. Wenn das Dataset mehrere Tabellen enthält, gibt es wahrscheinlich verschiedene Datenadapter für jede Tabelle, und Sie müssen die Fill-Methode jedes einzelnen Adapters aufrufen.

    Weitere Informationen zum Füllen von Datasets finden Sie unter Einführung in Datenadapter und Erstellen von Datenadaptern. Weitere Informationen zum Füllen eines Datasets mit einem Datenadapter finden Sie unter Auffüllen eines DataSets mit einem DataAdapter-Objekt.

  • Um die Tabellen im Dataset manuell zu füllen, erstellen Sie DataRow-Objekte und fügen sie der Rows-Auflistung der Tabelle hinzu. (Dies ist nur zur Laufzeit möglich. Zur Entwurfszeit kann die Rows-Auflistung nicht festgelegt werden.) Weitere Informationen finden Sie unter Hinzufügen von Daten zu einer Tabelle.

  • Lesen Sie ein XML-Dokument oder einen XML-Stream in das Dataset ein. Weitere Informationen finden Sie unter der Beschreibung der ReadXml-Methode.

  • Führen (Kopieren) Sie den Inhalt anderer Datasets zusammen. Dieses Szenario ist hilfreich, wenn die Anwendung Datasets von verschiedenen Quellen (z. B. verschiedenen XML-Webdiensten) erhält, sie jedoch in einem einzelnen Dataset konsolidieren muss. Weitere Informationen finden Sie unter der Beschreibung der DataSet.Merge-Methode.

Datensatzposition und Navigation in Datasets

Da ein Dataset ein vollständig separater Container für Daten ist, benötigen Datasets (im Gegensatz zu ADO-Recordsets) nicht das Konzept eines aktuellen Datensatzes und unterstützen es auch nicht. Stattdessen sind alle Datensätze im Dataset verfügbar.

Da es keinen aktuellen Datensatz gibt, gibt es auch keine bestimmte Eigenschaft, die auf einen aktuellen Datensatz zeigt. Außerdem gibt es keine Methoden oder Eigenschaften, um sich zwischen den Datensätzen zu bewegen. (Anders die ADO-Recordsets: Sie unterstützen eine absolute Datensatzposition und Methoden, um sich zwischen Datensätzen zu bewegen.) Sie können auf die einzelnen Tabellen im Dataset als Objekte zugreifen. Jede Tabelle stellt eine Auflistung von Zeilen zur Verfügung. Sie können diese wie eine beliebige Auflistung behandeln und über den Index der Auflistung auf die Zeilen zugreifen oder auflistungsspezifische Anweisungen in der Programmiersprache verwenden.

Hinweis   Wenn Sie Steuerelemente in einem Windows Forms an ein Dataset binden, können Sie die Bindungsarchitektur des Formulars verwenden, um den Zugriff auf die einzelnen Datensätze zu vereinfachen. Weitere Informationen finden Sie unter Navigieren durch Daten in Windows Forms.

Verknüpfte Tabellen und DataRelation-Objekte

Wenn es mehrere Tabellen in einem Dataset gibt, sind die Informationen in den Tabellen möglicherweise verknüpft. Ein Dataset besitzt kein inhärentes Wissen hinsichtlich solcher Beziehungen. Um mit Daten in verknüpften Tabellen arbeiten zu können, sollten Sie daher DataRelation-Objekte erstellen, die die Beziehung zwischen den Tabellen im Dataset beschreiben. DataRelation-Objekte können verwendet werden, um programmgesteuert für einen übergeordneten Datensatz verknüpfte untergeordnete Datensätze sowie den übergeordneten Datensatz eines untergeordneten Datensatzes abzurufen.

Nehmen Sie als Beispiel Kunden- und Auftragsdaten wie in der Northwind-Datenbank. Die Customers-Tabelle könnte folgende Datensätze enthalten:

CustomerID   CompanyName               City
ALFKI        Alfreds Futterkiste       Berlin
ANTON        Antonio Moreno Taquerias  Mexico D.F.
AROUT        Around the Horn           London

Das Dataset könnte auch eine andere Tabelle mit Auftragsinformationen enthalten. Die Orders-Tabelle enthält eine Kunden-ID als Fremdschlüsselspalte. Wenn Sie nur einige Spalten in der Orders-Tabelle auswählen, könnte dies wie folgt aussehen:

OrderId    CustomerID    OrderDate
10692      ALFKI         10/03/1997
10702      ALFKI         10/13/1997
10365      ANTON         11/27/1996
10507      ANTON         4/15/1997

Da es mehrere Aufträge pro Kunden geben kann, liegt eine 1:n-Beziehung zwischen Kunden und Aufträgen vor. In der Tabelle oben gibt es zwei Aufträge für den Kunden ALFKI.

Mit einem DataRelation-Objekt können Sie die verknüpften Datensätze aus einer untergeordneten oder übergeordneten Tabelle abrufen. Wenn Sie beispielsweise mit dem Datensatz für den Kunden ANTON arbeiten, wird die Auflistung der Datensätze abgerufen, aus denen die Aufträge für diesen Kunden hervorgehen. Entsprechend wird bei dem Datensatz für Auftragsnummer 10507 mit einem DataRelation-Objekt der Datensatz abgerufen, aus dem der zugehörige Kunde (ANTON) für den Auftrag hervorgeht.

Einschränkungen

Wie in den meisten Datenbanken unterstützen Datasets Einschränkungen, um die Integrität von Daten sicherzustellen. Einschränkungen sind Regeln, die beim Einfügen, Aktualisieren oder Löschen von Zeilen in einer Tabelle angewendet werden. Sie können zwei Arten von Einschränkungen definieren:

  • Eine Unique-Einschränkung, die überprüft, ob die neuen Werte in einer Spalte einmalig in der Tabelle sind.
  • Eine Fremdschlüsseleinschränkung, die Regeln dazu definiert, wie verknüpfte untergeordnete Datensätze aktualisiert werden sollen, wenn ein Datensatz in einer Mastertabelle aktualisiert oder gelöscht wird.

In einem Dataset sind Einschränkungen mit einzelnen Tabellen (Fremdschlüsseleinschränkungen) oder mit Spalten (eine Unique-Einschränkung, die sicherstellt, dass Spaltenwerte einmalig sind) verknüpft. Einschränkungen werden als Objekte vom Typ UniqueConstraint oder ForeignKeyConstraint implementiert. Anschließend werden sie der Constraints-Auflistung einer Tabelle hinzugefügt. Eine Unique-Einschränkung können Sie auch festlegen, indem Sie die Unique-Eigenschaft einer Datenspalte auf true setzen.

Das Dataset selbst unterstützt eine boolesche EnforceConstraints-Eigenschaft, die angibt, ob Einschränkungen erzwungen werden oder nicht. Diese Eigenschaft ist standardmäßig auf true gesetzt. In manchen Situationen ist es jedoch sinnvoll, Einschränkungen vorübergehend zu deaktivieren. Dies ist meistens dann der Fall, wenn Sie einen Datensatz so ändern, dass dies vorübergehend zu einem ungültigen Status führt. Nachdem Sie die Änderung abgeschlossen haben (und zum gültigen Status zurückgekehrt sind), können Sie die Einschränkungen wieder aktivieren.

In Visual Studio erstellen Sie Einschränkungen implizit beim Definieren eines Datasets. Wenn Sie einem Dataset einen Primärschlüssel hinzufügen, erstellen Sie implizit eine Unique-Einschränkung für die Spalte mit dem Primärschlüssel. Um für andere Spalten eine eindeutige Einschränkung festzulegen, setzen Sie deren Unique-Eigenschaft auf true.

Eine Fremdschlüsseleinschränkung legen Sie fest indem Sie ein DataRelation-Objekt in einem Dataset erstellen. Mit Hilfe eines DataRelation-Objekts können Sie nicht nur programmgesteuert Informationen zu verknüpften Datensätzen abrufen, sondern auch Regeln für Fremdschlüsseleinschränkungen definieren.

Weitere Informationen zur Verwendung von DataRelation-Objekten als Fremdschlüsseleinschränkungen finden Sie unter Einführung in DataRelation-Objekte. Weitere Informationen zum programmgesteuerten Erstellen von Einschränkungen finden Sie unter Hinzufügen von Einschränkungen zu einer Tabelle.

Aktualisieren von Datasets und Datenspeichern

Wenn Änderungen an Datensätzen im Dataset vorgenommen werden, müssen diese Änderungen in die Datenbank zurückgeschrieben werden. Rufen Sie die Update-Methode des Datenadapters auf, der die Kommunikation zwischen dem Dataset und der zugehörigen Datenquelle steuert, um Änderungen aus dem Dataset in die Datenbank zu schreiben.

Die DataRow-Klasse, mit der einzelne Datensätze bearbeitet werden, enthält die RowState-Eigenschaft, deren Werte angeben, ob und wie die Zeile geändert wurde, seit die Datentabelle zum ersten Mal aus der Datenbank geladen wurde. Mögliche Werte sind Deleted, Modified, New und Unchanged. Die Update-Methode untersucht den Wert der RowState-Eigenschaft, um zu ermitteln, welche Datensätze in die Datenbank geschrieben werden müssen und welcher Datenbankbefehl (zum Hinzufügen, Bearbeiten oder Löschen) aufgerufen werden muss.

Weitere Informationen über Aktualisierungsdaten finden Sie unter DataSet-Aktualisierungen in Visual Studio .NET.

Siehe auch

Einführung in den Datenzugriff mit ADO.NET | Einführung in Datenadapter | Tools in Visual Studio zum Erstellen von Datasets | Erstellen typisierter Datasets mit dem Komponenten-Designer | Erstellen von XML-Schemas und Datasets | Hinzufügen vorhandener typisierter Datasets zu Formularen oder Komponenten | Hinzufügen nicht typisierter Datasets zu Formularen oder Komponenten | Exemplarische Vorgehensweisen zur Arbeit mit Daten