![]() |
|
|||||
Tabelle 12.5 Steckbrief für die Klasse OleDbDataAdapter 12.6.2 Mehrere Tabellen in ein DataSet-Objekt einlesen
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Achtung Wenn Sie die eckigen Klammern weglassen, erhalten Sie die in Abbildung 12.12 gezeigte irreführende Fehlermeldung: Für mindestens einen erforderlichen Parameter wurde kein Wert angegeben. Dabei lokalisiert der Compiler die Fehlerursache in der Zeile myAdapter.Fill (myDS, "Personal"). Tatsächlich ist mit diesem Befehl aber alles in Ordnung. Auch die »erforderlichen Parameter« wurden der Fill-Methode korrekt übergeben. Wenn Sie die eckigen Klammern im SQL-Statement ergänzen, funktioniert es. |

Hier klicken, um das Bild zu Vergrößern
Abbildung 12.12 Ein fehlerhaftes SQL-Statement erzeugt diese irreführende Fehlermeldung.
Innerhalb eines DataSet-Objekts finden Sie die typische verschachtelte Struktur aus Tabellen, Zeilen und Spalten vor.
| Ein DataSet-Objekt enthält über seine Eigenschaft Tables eine DataTableCollection mit DataTable-Elementen. |
| Ein DataTable-Objekt enthält über die Eigenschaft Columns eine DataColumnCollection und über die Eigenschaft Rows eine DataRowCollection. |
| Eine DataRowCollection enthält Objekte vom Typ DataRow und eine DataColumnCollection enthält Objekte vom Typ DataColumn. |
Mit Hilfe dieser Objekte können Sie relativ einfach auf alle Bestandteile zugreifen. db_10.aspx zeigt, wie Sie einzelne Wert oder auch den gesamten Datenbestand eines DataSet-Objekts auslesen können. Abbildung 12.13 zeigt die Darstellung im Browser. Der Code ist bis zum zweiten Aufruf der Fill-Methode mit db_09.aspx identisch.
<!-- db_10.aspx -->
<!-- Der Code ist mit db_09.aspx bis zur ersten
folgenden Zeile identisch: -->
' ...
myAdapter.Fill (myDS, "Personal")
Dim myTable As DataTable
Dim myRow As DataRow
Dim myCol As DataColumn
Dim sb As New StringBuilder()
' Wie viele Tabellen enthält das Dataset?
sb.Append ("Das DataSet enthält ingesamt <b>")
sb.Append (myDS.Tables.count)
sb.Append ("</b> Tabellen. <br>")
' Den Wert einer einzelnen Zelle auslesen
myRow = myDS.Tables(1).Rows(1)
sb.Append ("Die zweite Tabelle enthält in der ")
sb.Append ("zweiten Zeile, zweite Spalte diesen ")
sb.Append ("Wert:<b> " & myRow(1).toString())
sb.Append ("</b>" )
' Alle Tabellen des Datasets ausgeben
For Each myTable in myDS.Tables
sb.Append ("<br><br>Tabellenname: <b>" )
sb.Append (myTable.TableName & "</b>")
For Each myRow in myTable.Rows
sb.Append ("<br>")
For Each myCol in myTable.Columns
sb.Append (myRow(myCol).toString())
sb.Append (" ---" )
Next myCol
Next myRow
Next myTable
ausgabe.innerHTML = sb.toString()
conn.Close()
End Sub
</script>
<html><head><title>
Auf einzelne Zeilen, Spalten und Tabellen
eines DataSet-Objekts gezielt zugreifen
</title></head>
<body>
<h3>Auf einzelne Zeilen, Spalten und Tabellen
eines DataSet-Objekts gezielt zugreifen</h3>
<p id="ausgabe" runat="server" />
</body></html>

Hier klicken, um das Bild zu Vergrößern
Abbildung 12.13 Mit den Klassen DataTable, DataRow und DataColumn greifen Sie gezielt auf die Bestandteile eines DataSet-Objekts zu.
Für den Zugriff auf eine einzelne Tabellenzelle verwenden Sie die Rows-Eigenschaft des DataTable-Objekts. Innerhalb eines DataRow-Objekts sprechen Sie eine einzelne Zelle anschließend entweder über die Ordinalzahl oder über den Feldnamen an. Der Ausdruck myRow(0) gibt den Inhalt des ersten Feldes zurück. myRow(1) nennt den Inhalt des zweiten Feldes usw. Hierbei kommt die mehrfach überladene Default-Eigenschaft Item zum Einsatz.
| Tipp Merken Sie sich, dass Sie für die Adressierung einer einzelnen Tabellenzelle erst die Zeile und dann die Spalte angeben. Andersherum führt kein Weg zur einzelnen Zelle. Ein DataColumn-Objekt verfügt also nicht über eine Rows-Eigenschaft oder etwas Ähnliches. Ein DataColumn-Objekt dient vorwiegend dazu, die Typmerkmale einer Spalte festzulegen. |
| Konstruktoren | |||
| New() New(String) |
Der Tabellenname kann übergeben werden. | ||
| Eigenschaften | |||
| CaseSensitive | Boolean | Gibt an, ob bei Vergleichen zwischen Zeichenfolgen die Groß- und Kleinschreibung berücksichtigt wird | |
| ChildRelations | DataRelationCollection | Eine DataRelationCollection mit den untergeordneten Beziehungen für diese Tabelle | |
| Columns | DataColumnCollection | Eine Auflistung von DataColumn-Objekten | |
| Constraints | ConstraintCollection | Eine Auflistung von Constraint-Objekten für diese Tabelle | |
| DataSet | DataSet | Das DataSet-Objekt, zu dem diese Tabelle gehört | |
| DefaultView | DataView | Das zugeordnete DataView-Objekt | |
| ExtendedProperties | PropertyCollection | Benutzerdefinierte Schlüssel-Wert-Paare | |
| HasErrors | Boolean | Gibt an, ob eine Zeile der Tabelle Fehler enthält. Sollte vor dem Zurückschreiben überprüft werden | |
| ParentRelations | DataRelationCollection | Die übergeordneten Beziehungen für diese Tabelle | |
| PrimaryKey | DataColumn() | Ein Array von Spalten, die als Primärschlüssel für die Tabelle verwendet werden | |
| Rows | DataRowCollection | Die Zeilen der Tabelle | |
| TableName | String | Der Name der Tabelle | |
| Methoden | |||
| AcceptChanges() | Übernimmt alle Änderungen, die an dieser Tabelle seit dem letzten Aufruf von AcceptChanges vorgenommen wurden | ||
| BeginLoadData() | Deaktiviert während des Ladens von Daten Benachrichtigungen, Indexverwaltung und Einschränkungen | ||
| Clear() | Löscht alle Daten aus der Tabelle | ||
| Clone() | Erstellt ein DataTable-Objekt mit dem gleichen Schema | ||
| Compute (expressionstring, filterstring) | Berechnet den Ausdruck für alle Zeilen, die auf den Filter-Ausdruck zutreffen | ||
| Copy() | Gibt ein DataTable-Objekt mit gleicher Struktur und Daten zurück | ||
| EndLoadData() | Aktiviert nach dem Laden von Daten Benachrichtigungen, Indexverwaltung und Einschränkungen | ||
| GetChanges() As DataTable | Gibt ein DataTable-Objekt zurück, das alle Änderungen enthält, die seit dem letzten Laden oder seit dem letzten Aufruf von AcceptChanges vorgenommen wurden | ||
| GetErrors() As DataRow() | Gibt ein Array von DataRow-Objekten zurück, die Fehler enthalten | ||
| ImportRow (DataRow) | Kopiert ein DataRow-Objekt in die Tabelle | ||
| LoadDataRow() | Nimmt ein Array von Werten an und sucht einen oder mehrere übereinstimmende Werte in der bzw. den Primärschlüsselspalten | ||
| NewRow() As DataRow | Erstellt eine neue DataRow mit dem Schema der Tabelle | ||
| RejectChanges() | Nimmt alle Änderungen zurück, die an der Tabelle seit dem Laden oder seit dem letzten Aufruf von AcceptChanges vorgenommen wurden | ||
| Reset() | Setzt die Tabelle in den ursprünglichen Zustand zurück | ||
| Select | Ruft ein Array von DataRow-Objekten ab | ||
Tabelle 12.6 Steckbrief der Klasse DataTable
| Konstruktor | ||||
| Um ein neues DataRow-Objekt zu erstellen, verwenden Sie die NewRow-Methode eines DataTable-Objekts. Die neu erstellte Zeile müssen Sie anschließend noch mit Add an die DataRowCollection anfügen. Beispiel:
Dim myRow as DataRow myRow = myTable.NewRow() myTable.Rows.Add (myRow) |
||||
| Eigenschaften | ||||
| HasErrors | Boolean | True, wenn die Zeile Fehler enthält | ||
| Item(String) Item(DataColumn) Item(Integer) |
Object | Default-Eigenschaft. Daten der angegebenen Spalte. Die Spalte kann benannt, als Ordinalzahl oder als DataColumn-Objekt übergeben werden. | ||
| ItemArray | Object() | Alle Werte der Zeile in Form eines Arrays von Objekten des Typs Object | ||
| RowError | String | Die benutzerdefinierte Fehlerbeschreibung für eine Zeile | ||
| RowState | DataRowState | Der aktuelle Zustand der Zeile in Bezug auf die DataRowCollection. Mögliche Werte sind Added, Deleted, Detached, Modified und Unchanged. | ||
| Table | DataTable | Die Tabelle, zu der diese Zeile gehört | ||
| Methoden | ||||
| AcceptChanges() | Übernimmt alle Änderungen an dieser Zeile, die seit dem letzten Aufruf von AcceptChanges() vorgenommen wurden | |||
| BeginEdit() | Beginnt einen Bearbeitungsvorgang für die Zeile | |||
| CancelEdit() | Bricht den aktuellen Bearbeitungsvorgang ab | |||
| ClearErrors() | Entfernt alle Fehler | |||
| Delete() | Markiert die Zeile als gelöscht | |||
| EndEdit() | Beendet den Bearbeitungsvorgang | |||
| GetChildRows(DataRelation) GetChildRows(String) u. a. |
DataRow() | Liefert für die übergebene DataRelation ein Array aus DataRow-Objekten mit den Kindzeilen | ||
| GetColumnError(DataColumn) GetColumnError(Integer) GetColumnError(String) |
String | Die Fehlerbeschreibung für eine Spalte | ||
| GetColumnsInError() | DataColumn() | Ein Array mit fehlerhaften Spalten | ||
| GetParentRow(DataRelation) GetParentRow(String) |
DataRow | Die übergeordnete Zeile in Bezug auf die übergebene Relation | ||
| GetParentRows(DataRelation) GetParentRows(String) |
DataRow() | Die übergeordnete Zeile in Bezug auf die übergebene Relation | ||
| HasVersion(DataRowVersion) | Boolean | True, wenn der gesuchte Bearbeitungszustand verfügbar ist. Möglich sind Current, Default, Original und Proposed. | ||
| IsNull(DataColumn) IsNull(Integer) IsNull(String) IsNull(DataColumn,DataRowVersion) |
Boolean | True, wenn die angegebene Spalte einen NULL-Wert enthält | ||
| RejectChanges() | Lehnt alle Änderungen ab, die seit dem letzten Aufruf von AcceptChanges an der Zeile vorgenommen wurden | |||
| SetColumnError(DataColumn, String) SetColumnError(Integer, String) SetColumnError(String, String) |
Die Fehlerbeschreibung für eine Spalte | |||
| SetParentRow(DataRow) SetParentRow(DataRow, DataRelation) |
Legt die übergeordnete Zeile fest | |||
Tabelle 12.7 Steckbrief der Klasse DataRow
| Konstruktoren | |||
| New() New(String) New(String,Type) New(String,Type,String) New(String,Type,String,MappingType) | Mögliche Parameter für den Konstruktor sind der Spaltenname, der Datentyp, ein Ausdruck z. B. für berechnete Spalten (entspricht der Eigenschaft Expression) und ein Wert, der bestimmt, ob die Spalte im XML-Zusammenhang als Attribut behandelt werden soll. | ||
| Eigenschaften | |||
| AllowDBNull | Boolean | True, wenn in der Spalte NULL-Werte zulässig sind | |
| AutoIncrement | Boolean | True, wenn der Spaltenwert für neue Zeilen automatisch erhöht werden soll | |
| AutoIncrementSeed | Long | Anfangswert für die AutoIncrement-Eigenschaft | |
| AutoIncrementStep | Long | Der Wert, um den der Spaltenwert jeweils erhöht werden soll. Standard ist 1. | |
| Caption | String | Spaltenbeschriftung. Wenn hier nichts angegeben wird, wird ColumnName verwendet. | |
| ColumnMapping | MappingType | Der MappingType der Spalte. Betrifft die Darstellung im XML-Kontext | |
| ColumnName | String | Der Name der Spalte in der DataColumnCollection | |
| DataType | Type | Spaltentyp | |
| DefaultValue | Object | Standardwert, muss dem DataType der Spalte entsprechen | |
| Expression | String | Ausdruck, der Zeilen filtert, die Werte der Spalte berechnen oder eine Aggregatspalte erstellen kann | |
| ExtendedProperties | PropertyCollection | Auflistung der Benutzerinformationen | |
| MaxLength | Integer | Maximale Länge einer Textspalte. Keine Beschränkung wird durch den Standardwert –1 signalisiert. | |
| Namespace | String | Der Namespace der DataColumn | |
| Ordinal | Integer | Die Position der Spalte in der DataColumnCollection | |
| Prefix | String | XML-Präfix, das als Alias für den Namespace der DataTable fungiert | |
| ReadOnly | Boolean | True, wenn die Spalte schreibgesschützt ist | |
| Table | DataTable | Die DataTable, zu der die Spalte gehört | |
| Unique | Boolean | True, wenn alle Werte der Spalte eindeutig sein müssen | |
Tabelle 12.8 Steckbrief der Klasse DataColumn
In relationalen Datenbanken sind Tabellen über Schlüsselfelder miteinander verbunden. Die Tabelle Personal verfügt beispielsweise über die Spalte Personal-Nr mit einer eindeutigen Identifikationsnummer für den jeweiligen Datensatz. Die Tabelle Bestellungen aus der Nordwind-Datenbank enthält ebenfalls eine Spalte Personal-Nr. Auf diese Weise lässt sich festhalten, welcher Angestellte welche Bestellung bearbeitet hat. Typischerweise ergeben sich hier 1:n-Beziehungen. Zu einem Datensatz aus der Personal-Tabelle passen jeweils viele Datensätze aus der Bestellungen-Tabelle.
| Achtung Wenn Sie Tabellen aus einer Datenbank in ein DataSet-Objekt übertragen, werden solche Relationen nicht automatisch mit übertragen, sondern Sie müssen sie ausdrücklich festlegen. |
So legen Sie eine Relation zwischen zwei Tabellen über die jeweiligen Schlüsselfelder fest:
1. Erstellen Sie ein DataColumn-Objekt von der Schlüssel-Spalte der Haupttabelle. Im Beispiel ist das das Feld Personal-Nr der Tabelle Personal. Dim parentCol As DataColumnWenn Sie die Tabellendaten auswerten, ergeben sich im Bezug auf Relationen zwei typische Situationen:
| Ausgehend von der Zeile einer Haupttabelle möchten Sie auf die zugehörigen Einträge in einer Kindtabelle zugreifen. |
| Oder genau andersherum: Von einem Eintrag in einer Kindtabelle möchten Sie auf die zugehörige Haupttabelle zugreifen. |
So erreichen Sie die zugehörigen Einträge der Kind-Tabelle:
Die DataRow-Klasse bietet die Methode GetChildRows() an. Sie übergeben der Methode GetChildRows() den Namen der gewünschten Relation und erhalten die zugehörigen Einträge der Kind-Tabelle in Form eines Arrays von DataRow-Objekten.
Für den umgekehrten Weg bietet die DataRow-Klasse die Methoden GetParentRow() und GetParentRows() an. Auch hier übergeben Sie den Namen der Relation und erhalten ein einzelnes DataRow-Objekt oder ein Array aus DataRow-Objekten.
db_11.aspx fasst die vorgestellten Schritte in einem Skript zusammen. Abbildung 12.14 zeigt die Darstellung im Browser. Für jeden Angestellten, den die Personal-Tabelle verzeichnet, werden diejenigen Bestellungen aufgelistet, die er bearbeitet hat.
<!-- db_11.aspx -->
<%@ Page Language="VB" Debug="True" Strict="True" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Sub Page_Load (ByVal Sender As Object, _
ByVal E As EventArgs)
' Verbindungszeichenfolge zusammensetzen
Dim connStr As String
connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
connStr += _
"Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
' Verbindung herstellen
Dim conn As New OleDbConnection(connStr)
conn.Open()
' Kommando-Objekt vorbereiten
Dim cmd As New OleDbCommand()
cmd.Connection = conn
' Adapter-Objekt vorbereiten
Dim myAdapter As New OleDbDataAdapter()
myAdapter.SelectCommand = cmd
' DataSet-Objekt vorbereiten
Dim myDS As New DataSet()
' Einige Spalten aus der Tabelle "Personal" einlesen
Dim sql1 As String
sql1 = "SELECT [Personal-Nr], Vorname, Nachname "
sql1 += "FROM Personal"
cmd.CommandText = sql1
myAdapter.Fill (myDS, "Personal")
' Einige Spalten aus der Tabelle "Bestellungen"
' einlesen
Dim sql2 As String
sql2 = "SELECT [Personal-Nr], Bestelldatum, " & _
"[Bestell-Nr], Empfänger FROM Bestellungen"
cmd.CommandText = sql2
myAdapter.Fill (myDS, "Bestellungen")
' Relation zwischen "Personal" und "Bestellungen"
' definieren:
' Die beteiligten Spalten festlegen.
Dim parentCol As DataColumn
Dim childCol As DataColumn
parentCol = _
myDS.Tables("Personal").Columns("Personal-Nr")
childCol = _
myDS.Tables("Bestellungen").Columns("Personal-Nr")
' Die Relation erstellen ...
Dim myRel As DataRelation
myRel = New DataRelation _
("bearbeitet von", parentCol, childCol)
' ... und dem Dataset hinzufügen.
myDS.Relations.Add (myRel)
Dim sb As New StringBuilder
sb.Append ("Wer hat welche Bestellungen ")
sb.Append ("bearbeitet?<br><br>")
Dim persRow As DataRow
Dim bestRow As DataRow
Dim myDate as DateTime
' Den Namen des Angestellten ausgeben
For Each persRow In myDS.Tables("Personal").Rows
sb.Append ("<br><b>" & _
persRow("Vorname").toString() & _
" " & _
persRow("Nachname").toString() & _
"</b><ul>")
' Die zugeordneten Bestellungen ausgeben
sb.Append("Bestelldatum – Bestell-Nr – Kunde")
For Each bestRow In persRow.getChildRows _
("bearbeitet von")
sb.Append ("<li>")
myDate = CDate(bestRow(1))
sb.Append (myDate.toShortDateString)
sb.Append (", ")
sb.Append (bestRow(2).toString() & ", ")
sb.Append (bestRow(3).toString() & ", ")
Next
sb.Append ("</ul>")
Next
ausgabe.innerHTML = sb.toString()
conn.Close()
End Sub
</script>
<html><head><title>
Relationen zwischen Tabellen verwenden</title></head>
<body>
<h3>Relationen zwischen Tabellen verwenden</h3>
<p id="ausgabe" runat="server" />
</body></html>

Hier klicken, um das Bild zu Vergrößern
Abbildung 12.14 Mit Hilfe von DataRelation-Objekten stellen Sie Relationen zwischen Haupttabellen und Kindtabellen her.
| << zurück |
| ||||||||||||
| ||||||||||||
| ||||||||||||
| ||||||||||||
| ||||||||||||
| ||||||||||||
Copyright © Galileo Press GmbH 2003
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.