Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 26 Offline mit DataSet
Pfeil 26.1 Das DataSet-Objekt verwenden
Pfeil 26.1.1 Ein DataSet-Objekt erzeugen
Pfeil 26.1.2 Anatomie einer DataTable
Pfeil 26.1.3 Zugriff auf eine Tabelle im DataSet
Pfeil 26.1.4 Zugriff auf die Ergebnisliste
Pfeil 26.1.5 Dateninformationen in eine XML-Datei schreiben
Pfeil 26.2 DataSet mit Schemainformationen
Pfeil 26.2.1 Schemainformationen bereitstellen
Pfeil 26.2.2 Gültigkeitsprüfung in einer DataColumn
Pfeil 26.2.3 Constraints-Klassen einer DataTable
Pfeil 26.2.4 Tabellenschema durch Programmcode
Pfeil 26.2.5 Tabellenschema durch DataAdapter
Pfeil 26.2.6 Tabellenschema aus einer XML-Datei
Pfeil 26.3 Änderung einer Tabelle
Pfeil 26.3.1 Editieren einer Datenzeile
Pfeil 26.3.2 Löschen einer Datenzeile
Pfeil 26.3.3 Neue Datenzeile hinzufügen
Pfeil 26.4 Änderung einer Datenzeile
Pfeil 26.4.1 Aktualisierungszustand
Pfeil 26.4.2 Ursprünglicher und aktualisierter Inhalt
Pfeil 26.4.3 Zeilenstatus manuell steuern
Pfeil 26.5 Mit mehreren Tabellen arbeiten
Pfeil 26.5.1 JOIN-Abfragen
Pfeil 26.5.2 Mehrere Tabellen in einem DataSet
Pfeil 26.5.3 Tabellenbeziehungen erzeugen
Pfeil 26.5.4 DataRelations und Einschränkungen
Pfeil 26.5.5 In Beziehung stehende Daten suchen
Pfeil 26.5.6 Ergänzung zum Speichern von Schemainformationen in einer XML–Schemadatei
Pfeil 26.6 Suchen und Filtern
Pfeil 26.6.1 Find
Pfeil 26.6.2 Select
Pfeil 26.7 Objekte vom Typ DataView
Pfeil 26.7.1 Initialisierung
Pfeil 26.7.2 Zugriff auf die Datenzeilen
Pfeil 26.7.3 Spalten durchsuchen
Pfeil 26.7.4 Mehrdeutige Suchergebnisse
Pfeil 26.7.5 Datenfilter
Pfeil 26.7.6 Statusfilter
Pfeil 26.7.7 Änderungen
Pfeil 26.7.8 DataView in DataTable umwandeln


Rheinwerk Computing - Zum Seitenanfang

26.2 DataSet mit Schemainformationen Zur nächsten ÜberschriftZur vorigen Überschrift

Sie können zur Verarbeitung von Daten eine DataTable editieren, neue Datenzeilen hinzufügen oder vorhandene löschen. Wie das gemacht wird, werden Sie später in diesem Kapitel noch sehen. Unabhängig davon, welche Änderungen Sie vorgenommen haben, betreffen diese zunächst nur das DataSet. Die Originaldatenbank weiß davon nichts. Erst zu einem späteren Zeitpunkt werden die Aktualisierungen mit der Update-Methode des DataAdapters zur Originaldatenbank übermittelt und dort gespeichert.

Oft müssen Spalten einer Tabelle der Datenbank Gültigkeitsregeln beachten: Beispielsweise lassen einige nur eine maximale Zeichenanzahl zu, andere schreiben einen eindeutigen Eintrag innerhalb der Datensätze der Tabelle vor oder lassen keinen NULL-Wert zu. Eine DataTable, die wir mit Fill füllen, ist hingegen sehr dumm. Sie enthält zwar alle angeforderten Daten, weiß aber nichts von den Gültigkeitsregeln, die in der Datenbank festgelegt sind. Die Folge ist, dass die Anwendung die Daten beliebig verändern kann, ohne dass eine Überprüfung erfolgt. Der anschließende Versuch, die Änderungen in die Datenbank zu schreiben, wird jedoch möglicherweise scheitern, weil die Datenbank vor der endgültigen Aktualisierung zuerst die Änderungen mit den Gültigkeitsregeln vergleicht und eine Verletzung feststellen wird. Es kommt zu einer Ausnahme.

Im folgenden Beispielprogramm können Sie das ausprobieren. Hierzu dient wieder die bekannte Tabelle Products der Northwind-Datenbank. Das Programm ermöglicht es uns, die Lagermenge des ersten Artikels zu ändern – es handelt sich dabei um Chai. Dazu werden Sie an der Konsole aufgefordert. Die Änderung wird zuerst in das DataSet geschrieben, anschließend wird die Originaldatenbank aktualisiert. Die Aktualisierungslogik mit der Methode Update des DataAdapters sowie das zuvor erzeugte Objekt vom Typ CommandBuilder soll uns an dieser Stelle nicht interessieren.


'...\ADO\DataSet\Inkonsistenz.vb

Option Strict On 
Imports System.Data.Common, System.Data.SqlClient 
Namespace ADO 
  Module Inkonsistenz 
    Sub Test() 
      Dim con As DbConnection = New SqlConnection() 
      con.ConnectionString = "Data Source=(local);" & _ 
          "Initial Catalog=Northwind;Integrated Security=sspi" 
      Dim cmd As DbCommand = New SqlCommand() 
      cmd.CommandText = _ 
        "SELECT Top 2 ProductID, ProductName, UnitsInStock FROM Products" 
      cmd.Connection = con

      Dim ds As New DataSet() 
      Dim da As DbDataAdapter = New SqlDataAdapter() 
      da.SelectCommand = cmd 
      da.Fill(ds) 
      Print(ds)

      Console.Write("UnitsInStock-Änderung des ersten Produkts: ") 
      ds.Tables(0).Rows(0)("UnitsInStock") = Console.ReadLine() 
      Dim cmb As DbCommandBuilder = New SqlCommandBuilder() 
      cmb.DataAdapter = da

      Try 
        da.Update(ds) 
      Catch ex As SqlException 
        Console.WriteLine("Fehler: {0}", ex.Message) 
      End Try 
      Print(ds)

      ds.Clear() : da.Fill(ds) 
      Print(ds)

      Console.ReadLine() 
    End Sub

    Sub Print(ByVal ds As DataSet) 
      Console.WriteLine("Produkte: ") 
      For Each row As DataRow In ds.Tables(0).Rows 
        Console.WriteLine("{0,2}{1,35}{2,3}", row(0), row(1), row(2)) 
      Next 
    End Sub 
  End Module 
End Namespace

Das Feld UnitsInStock in der Datenbank darf nicht negativ sein. Sollten Sie gegen diese Beschränkung verstoßen, wird eine Ausnahme vom Typ SqlException ausgelöst, die von der Datenbank initiiert wird. Die geänderte Spalte im DataSet hatte keinen Einwand gegen die vorgenommene Änderung, denn bekanntlich sind die Daten im DataSet dumm. Der Versuch, sie endgültig zu aktualisieren, scheitert jedoch an der Feldlängenbegrenzung in der Datenbank. Die folgende Ausgabe zeigt, dass die Originaldaten unverändert bleiben:

Produkte: 
 1                               Chai 39 
 2                              Chang 17 
UnitsInStock-Änderung des ersten Produkts: –2 
Fehler: Die UPDATE-Anweisung steht in Konflikt mit der CHECK-Einschränkung 
"CK_UnitsInStock". Der Konflikt trat in der "Northwind"-Datenbank, Tabelle 
"dbo.Products", column 'UnitsInStock' auf. 
Die Anweisung wurde beendet. 
Produkte: 
 1                               Chai –2 
 2                              Chang 17 
Produkte: 
 1                               Chai 39 
 2                              Chang 17

Obwohl aufgrund der Einschränkungen in der Datenbank sichergestellt ist, dass keine unzulässigen Daten geschrieben werden, stellt der gezeigte Ansatz keine gute Lösung dar. Denken Sie nur an eine stark frequentierte Datenbank im Internet. Jeder Anwender, der unzulässige Daten übermittelt, würde von der Datenbank in Form einer Ausnahme über das Scheitern der Aktualisierung informiert. Der Datenfluss von der Datenbank zum Anwender würde nicht nur das Netz belasten, sondern auch die Performance der Anwendung verschlechtern.


Rheinwerk Computing - Zum Seitenanfang

26.2.1 Schemainformationen bereitstellen Zur nächsten ÜberschriftZur vorigen Überschrift

Besser ist es, wenn bereits das DataSet die Gültigkeitsregeln kennt. So können Änderungen überprüft werden, bevor sie der Datenbank übermittelt werden. In unserem Beispiel hätte dann das DataSet eine negative Menge abgelehnt, ohne die Datenbank zu kontaktieren.

Damit DataSet die Gültigkeit prüfen kann, werden Schemainformationen benötigt, die einer Anwendung auf drei verschiedene Arten bereitgestellt werden können:

  • Die Schemainformationen werden mittels Programmcode für alle betreffenden Tabellen und Spalten explizit festgelegt.
  • Die Schemainformationen werden von der Datenbank mit der Methode FillSchema sowie der Eigenschaft MissingSchemaAction des DataAdapters bezogen.
  • Die Schemainformationen werden aus einer XML-Schemadatei bezogen.

Schemainformationen beschreiben Datenüberprüfungsmechanismen, die sogenannten Einschränkungen (Constraints). Sie wirken auf Spalten- und Tabellenebene, die von einer DataTable und einer DataColumn unterstützt werden. Ich erkläre erst, wie die Einschränkungen in ADO.NET realisiert sind, und dann die Zusammenarbeit mit DataSet.


Rheinwerk Computing - Zum Seitenanfang

26.2.2 Gültigkeitsprüfung in einer DataColumn Zur nächsten ÜberschriftZur vorigen Überschrift

Um die in der Anwendung eingegebenen Daten mittels Programmcode zu überprüfen, stellt das DataColumn-Objekt, mit dem eine Spalte der Abfrage beschrieben wird, einige Eigenschaften zur Verfügung (siehe Tabelle 26.1). Weitere Einschränkungen speichert die Constraints-Auflistung einer DataTable.


Tabelle 26.1 Gültigkeitsbeschreibende Eigenschaften einer DataColumn

Eigenschaft Beschreibung

AllowDBNull

Legt fest, ob eine Spalte den Wert NULL akzeptiert oder nicht.

AutoIncrement

Automatische Nummerierung von Zeilen (keine eigenen Werte)

DataType

Datentyp der Werte (Meist erfolgt die Gültigkeitsprüfung bereits durch den korrespondierenden .NET-Typ.)

Expression

Ausdruck zur Berechnung des Wertes in einer Spalte

MaxLength

Maximale Anzahl der Zeichen in einer Zeichenfolge in einer Spalte

ReadOnly

Mit dem Wert True sind die Daten einer Spalte vor dem Überschreiben geschützt.

Unique

Für True ist sichergestellt, dass alle Werte einer Spalte verschieden sind.



Rheinwerk Computing - Zum Seitenanfang

26.2.3 Constraints-Klassen einer DataTable Zur nächsten ÜberschriftZur vorigen Überschrift

Zwei von der Basisklasse Constraint abgeleitetete Klassen beschreiben die Einschränkungen einer DataTable:

  • UniqueConstraint
  • ForeignKeyConstraint

Da eine DataTable mehrere Einschränkungen haben kann, werden alle Constraint-Objekte in einer Auflistung des Typs ConstraintCollection verwaltet, die über die Eigenschaft Constraints der DataTable erreichbar ist.


Hinweis
Eine Verletzung einer Einschränkung erzeugt eine Ausnahme, die Sie in Ihrem Code abfangen sollten.


UniqueConstraint

Ein UniqueConstraint-Objekt wird automatisch angelegt, wenn die Eigenschaft Unique einer Spalte auf True gesetzt wird. Gleichzeitig wird das Objekt der ConstraintCollection hinzugefügt. Sie können ein UniqueConstraint-Objekt natürlich auch im Code erzeugen und dessen Eigenschaft Columns die Spalte übergeben, auf der die Einschränkung gesetzt wird. Die Eigenschaft Unique einer Spalte zu setzen ist aber einfacher. Trotzdem kann das explizite Erzeugen sinnvoll sein. Das ist der Fall, wenn Sie sicherstellen müssen, dass die Kombination von Werten aus mehreren Spalten eindeutig ist.

ForeignKeyConstraint

Mit einem ForeignKeyConstraint-Objekt können Sie festlegen, wie sich eine Beziehung zwischen Tabellen bezüglich Datenänderungen auswirken soll. In der Tabelle Products der North-wind-Datenbank muss die Spalte CategoryID einen Wert enthalten, der in der Tabelle Categories enthalten ist. Der Spalte CategoryID wird dazu ein ForeignKeyConstraint-Objekt zugeordnet. Allerdings müssen Sie dieses nicht explizit erzeugen. Wenn Sie im DataSet eine Beziehung zwischen zwei Tabellen einrichten, wird automatisch ein ForeignKeyConstraint-Objekt erzeugt. Wir werden auf das Thema der Einrichtung einer Beziehung zwischen zwei Tabellen in Abschnitt 26.5, »Mit mehreren Tabellen arbeiten«, zurückkommen.

Primärschlüsselfelder

Primärschlüssel werden in der DataTable definiert. Die entsprechende Eigenschaft heißt PrimaryKey. Dass ein Primärschlüssel nicht die Eigenschaft einer DataColumn ist, liegt daran, dass viele Tabellen mehrere Spalten zu einem gemeinsamen Primärschlüssel kombinieren. Die PrimaryKey-Eigenschaft der DataTable beschreibt deshalb auch ein Array von DataColumn-Objekten. Beim Festlegen der PrimaryKey-Eigenschaft wird ein UniqueConstraint-Objekt erzeugt, um die Primärschlüsseleinschränkung durchzusetzen.

CHECK-Einschränkungen

Zu CHECK-Einschränkungen auf Datenbankebene gibt es keine korrespondierende Klasse in ADO.NET. Wollen Sie eine der Constraint-Klassen beerben, müssen Sie mit Reflection arbeiten, da die entscheidende Methode, Friend Overrides Sub CheckConstraint(row As DataRow, action As DataRowAction), keinen öffentlichen Zugriff erlaubt.

Einfacher ist die Registrierung einer Methode für das ColumnChanging-Ereignis. Bei Verletzung der Einschränkung lösen Sie dann eine Ausnahme aus. Dies ist auch der Mechanismus, den die eingebauten Einschränkungen nutzen.


Rheinwerk Computing - Zum Seitenanfang

26.2.4 Tabellenschema durch Programmcode Zur nächsten ÜberschriftZur vorigen Überschrift

Verhältnismäßig aufwändig ist die Bereitstellung eines Schemas durch die Eigenschaften AllowDBNull, MaxLength und Unique einer DataColumn sowie der Eigenschaft PrimaryKey einer DataTable. Mit ReadOnly=True haben Sie zudem die Möglichkeit, gültige Daten vor einer Veränderung durch den Benutzer zu schützen.

Im folgenden Beispiel soll die Bestellmenge eines Produkts der Tabelle Products geändert werden. Ein ähnliches Beispiel habe ich ein paar Seiten zuvor schon einmal gezeigt. Diesmal wird die DataTable im DataSet jedoch mit den Schemainformationen für die abgefragten Felder gefüllt. Der erste Codeabschnitt zeigt den Rahmen: Kommando und DataAdapter erzeugen, Schema im Code erzeugen (Schema, siehe unten), Ausdruck der Originaltabelle (Print, siehe unten), Änderung von Werten und Ausdruck der neuen Tabelle. Die Synchronisation mit dem Datenbankserver ist weggelassen.


'...\ADO\DataSet\SchemaDurchCode.vb

Option Strict On 
Imports System.Data.Common, System.Data.SqlClient 
Namespace ADO 
  Module SchemaDurchCode 
    Sub Test() 
      Dim con As DbConnection = New SqlConnection() 
      con.ConnectionString = "Data Source=(local);" & _ 
          "Initial Catalog=Northwind;Integrated Security=sspi" 
      Dim cmd As DbCommand = New SqlCommand() 
      cmd.CommandText = _ 
        "SELECT Top 2 ProductID, ProductName, UnitsInStock FROM Products" 
      cmd.Connection = con

      Dim ds As New DataSet() 
      Dim da As DbDataAdapter = New SqlDataAdapter() 
      da.SelectCommand = cmd 
      da.Fill(ds)

      Schema(ds.Tables(0)) 
      Print(ds)

      Try 
        Console.Write("UnitsInStock-Änderung des ersten Produkts: ") 
        ds.Tables(0).Rows(0)("UnitsInStock") = Console.ReadLine()

        Console.Write("ProductName-Änderung des ersten Produkts: ") 
        ds.Tables(0).Rows(0)("ProductName") = Console.ReadLine() 
      Catch ex As Exception 
        Console.WriteLine("Falscher Wert: {0}.", ex.Message) 
      End Try 
      Print(ds)

      Console.ReadLine() 
    End Sub 
    ... 
  End Module 
End Namespace

Die Metainformation wird in Schema erstellt. Die maximale Länge der Produktbezeichnung und das Verbieten von NULL-Werten wird auf Spaltenebene festgelegt, der Primärschlüssel auf Tabellenebene. Zur Überprüfung der Mengenangaben wird der Ereignishandler Positiv definiert und beim Ereignis registriert. Im Fall einer Verletzung wird eine Ausnahme ausgelöst.


'...\ADO\DataSet\SchemaDurchCode.vb

Option Strict On 
Imports System.Data.Common, System.Data.SqlClient 
Namespace ADO 
  Module SchemaDurchCode 
    ... 
    Sub Schema(ByVal tbl As DataTable) 
      tbl.PrimaryKey = New DataColumn() {tbl.Columns("ProductID")} 
      tbl.Columns("ProductName").MaxLength = 10 
      tbl.Columns("ProductName").AllowDBNull = False 
      AddHandler tbl.ColumnChanging, AddressOf Positiv 
    End Sub

    Sub Positiv(ByVal sender As Object, ByVal ev As DataColumnChangeEventArgs) 
      If ev.Column.ColumnName = "UnitsInStock" AndAlso _ 
        CType(ev.ProposedValue, Int16) < 0 Then _ 
        Throw New ApplicationException("negativ") 
    End Sub

    Sub Print(ByVal ds As DataSet) 
      Console.WriteLine("Produkte: ") 
      For Each row As DataRow In ds.Tables(0).Rows 
        Console.WriteLine("{0,2}{1,35}{2,3}", row(0), row(1), row(2)) 
      Next 
    End Sub 
  End Module 
End Namespace

Die folgende Ausgabe zeigt die durch die negative Mengenangabe erzeugte Ausnahme im Ereignishandler:

Produkte:

 1                               Chai 39 
 2                              Chang 17 
UnitsInStock-Änderung des ersten Produkts: –2 
Falscher Wert: negativ. 
Produkte: 
 1                               Chai 39 
 2                              Chang 17

Ein zu langer Produktname wird von der Spalteneinschränkung zurückgewiesen. Die vorher gesetzte Menge von 20 bleibt davon unberührt:

Produkte: 
 1                               Chai 39 
 2                              Chang 17 
UnitsInStock-Änderung des ersten Produkts: 20 
ProductName-Änderung des ersten Produkts: Kamillentee 
Falscher Wert: Cannot set column 'ProductName'. The value violates the 
  MaxLength limit of this column.. 
Produkte: 
 1                               Chai 20 
 2                              Chang 17

Da nach dem Füllen des DataSets kein Kontakt zum Datenbankserver aufgebaut wird, ist sichergestellt, dass die Prüfung komplett auf Clientseite stattfindet. Der Datenbankserver ist also entlastet.


Rheinwerk Computing - Zum Seitenanfang

26.2.5 Tabellenschema durch DataAdapter Zur nächsten ÜberschriftZur vorigen Überschrift

FillSchema

Enthält ein DataSet mehrere Tabellen mit jeweils verhältnismäßig vielen Spalten, kann die Codierung der Schemainformationen eine ziemlich aufwändige, aber auch langweilige Aufgabe sein. Mit der Methode FillSchema des DataAdapters können Sie alle Schemainformationen für das DataSet oder die DataTable bei der Datenbank abrufen.

Grundlage ist dabei das in SelectCommand beschriebene SELECT-Kommando. Als Ergebnis des FillSchema-Aufrufs werden die Eigenschaften ReadOnly, AllowDBNull, AutoIncrement, Unique und MaxLength der in der Abfrage enthaltenen Spalten gesetzt und die Eigenschaften PrimaryKey und Constraints der entsprechenden Tabelle festgelegt.

Alle Überladungen von FillSchema erwarten ein Argument vom Typ der in Tabelle 26.2 gezeigten Enumeration SchemaType. Der Parameter steuert, ob die Spaltenzuordnungen in der DataTableMappingCollection und der DataColumnMappingCollection benutzt werden.


Tabelle 26.2 Konstanten der Enumeration »SchemaType«

Konstante Beschreibung

Mapped

Der DataAdapter verwendet die Spaltenzuordnungen.

Source

Der DataAdapter ignoriert die Spaltenzuordnungen.


Wenn Sie mittels Programmcode die Gültigkeitsregeln beschreiben, können diese zu jedem beliebigen Zeitpunkt gesetzt werden, also auch nach dem Füllen des DataSets. Es muss aber vor der Aktualisierung der Daten sein. Ziehen Sie die Methode FillSchema vor, muss diese vor dem Füllen des DataSets aufgerufen werden:

... 
Dim ds As DataSet = New DataSet() 
da.FillSchema(ds, SchemaType.Source) 
da.Fill(ds) 
...

Der Aufruf der Methode ist natürlich sehr bequem. Sie dürfen dabei aber nicht vergessen, dass dabei sowohl das Netzwerk als auch die Datenbank belastet werden.

MissingSchemaAction

Der DataAdapter ist so eingestellt, dass Spalten zu einer DataTable hinzugefügt werden, wenn diese in der DataTable noch nicht existieren. Damit stellt der DataAdapter sicher, die Ergebnisse einer Abfrage speichern zu können. Geändert wird dieses Verhalten durch die Eigenschaft MissingSchemaAction, die Werte der gleichnamigen Aufzählung beschreibt (siehe Tabelle 26.3).


Tabelle 26.3 Konstanten der Enumeration »MissingSchemaAction«

Konstante Beschreibung

Add

Fügt die erforderlichen Spalten zum Vervollständigen des Schemas hinzu.

AddWithKey

Eine nicht in der DataTable enthaltene Spalte wird hinzugefügt, und es werden MaxLength sowie AlloDBNull gesetzt. Wenn die DataTable noch nicht existiert, wird aus der Datenbank der Primärschlüssel ermittelt.

Error

Werden Daten gelesen, die nicht in das Schema passen, wird die Ausnahme InvalidOperation ausgelöst.

Ignore

Ignoriert die zusätzlichen Spalten.


Hat die Eigenschaft MissingSchemaAction den Wert AddWithKey, werden ähnlich wie mit der Methode FillSchema die Schemainformationen abgerufen. Diese sind jedoch auf den Primärschlüssel der Tabelle sowie die Einschränkungen AllowDBNull und MaxLength der Spalten beschränkt. Unique, AutoIncrement und ReadOnly werden nicht berücksichtigt.


Rheinwerk Computing - Zum Seitenanfang

26.2.6 Tabellenschema aus einer XML-Datei topZur vorigen Überschrift

Nun kennen Sie zwei Varianten, um Metadaten einer Tabelle im DataSet bereitzustellen. Sie wissen, dass es sehr einfach ist, mit FillSchema oder MissingSchemaAction=AddWithKey zu arbeiten. Der Nachteil dabei ist die erhöhte Belastung des Netzes und der Datenbank. Die Methode ist daher eher für Ad-hoc-Abfragen geeignet. Die Schemainformationen mittels Programmcode zu beschreiben ist bezüglich der Laufzeit effektiv, weil das Netz und die Datenbank nur die Daten selbst liefern müssen, während die Metadaten im Code beschrieben werden. Allerdings bedeutet das einen nicht unerheblichen Programmieraufwand.

Als dritte, praxisgerechte Möglichkeit stellt DataSet mit WriteXmlSchema und ReadXmlSchema zwei Methoden zur Verfügung, die das Schema in XML beschreiben. WriteXmlSchema schreibt die Schemainformationen eines DataSets in ein XML-Dokument, ReadXmlSchema liest ein solches Schema ein. Das Schema enthält Definitionen von Tabellen und Einschränkungen. XML-Schemadateien haben üblicherweise die Dateiendung .xsd.

Bevor Sie das Schema eines DataSets in einer Schemadatei speichern, muss das Schema im DataSet bekannt sein. Sie können sich dieses daher zur Entwicklungszeit mit FillSchema besorgen und anschließend mit WriteXmlSchema in einer Datei speichern:

ds.WriteXmlSchema("C:MyDataSetSchema.xsd")

Die erzeugte Schemadatei muss zusammen mit der Anwendung ausgeliefert werden. Im folgenden Listing sehen Sie die Schemadatei einer Abfrage der Spalten ProductID und ProductName der Tabelle Products:

<?xml version="1.0" standalone="yes"?> 
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/
XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
  <xs:element name="NewDataSet" msdata:IsDataSet="true" 
  msdata:UseCurrentLocale="true"> 
    <xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"> 
      <xs:element name="Table"> 
        <xs:complexType><xs:sequence> 
          <xs:element name="ProductID" msdata:ReadOnly="true" 
            msdata:AutoIncrement="true" type="xs:int" /> 
          <xs:element name="ProductName"><xs:simpleType> 
            <xs:restriction base="xs:string 
              <xs:maxLength value="40" /> 
            </xs:restriction> 
          </xs:simpleType></xs:element> 
        </xs:sequence></xs:complexType> 
      </xs:element> 
    </xs:choice></xs:complexType> 
    <xs:unique name="Constraint1" msdata:PrimaryKey="true"> 
      <xs:selector xpath=".//Table" /> 
      <xs:field xpath="ProductID" /> 
    </xs:unique> 
  </xs:element> 
</xs:schema>

Sie können erkennen, dass die Spalte ProductID die Primärschlüsselspalte der Tabelle beschreibt. AutoIncrement=True signalisiert, dass der Spaltenwert bei einer neu hinzugefügten Spalte automatisch erhöht wird. Infolgedessen gilt für die Spalte auch ReadOnly=True. Die Spalte ProductName ist auf maximal 40 Zeichen begrenzt.

Die Auswertung einer Schemadatei ist sehr einfach. Zur Laufzeit erzeugen Sie zuerst das DataSet-Objekt, lesen anschließend die Schemadatei ein und füllen danach das DataSet mit den Daten:

... 
Dim ds As DataSet = New DataSet() 
ds.ReadXmlSchema("C:MyDataSetSchema.xsd") 
da.Fill(ds)

Daten und Schema in eine Datei schreiben

Mit WriteXmlSchema erzeugen Sie eine Schemadatei, die die Metadaten des DataSets beinhaltet. Analog sichert WriteXml von DataSet die Daten in einer XML-Datei.

Metadaten und Dateninformationen müssen Sie nicht in getrennten Dateien speichern. Mit einer Überladung von WriteXml lässt sich der aktuelle Inhalt des DataSets als XML-Daten mit den Metadaten als XSD-Inlineschema beschreiben, d. h., sowohl Daten als auch Schema sind in einer Datei gespeichert.

ds.WriteXml("C:ContentsOfdataSet.xml", XmlWriteMode.WriteSchema)

Das Auslassen des zweiten Parameters ist äquivalent zu XmlWriteMode.IgnoreSchema.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual Basic 2008
Visual Basic 2008
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Visual Basic 2012






 Visual Basic 2012


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern