72
Stefan Fellner Visual Basic .NET und Datenbanken

Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Embed Size (px)

Citation preview

Page 1: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Stefan Fellner

Visual Basic .NET und Datenbanken

Page 2: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Inhalt 5

Inhalt

Einleitung 13

Ein Neubeginn mit Visual Basic .NET 14Update oder Neuschöpfung? 14

Die neue Datenbanktechnologie ADO.NET 17Es war einmal ein Recordset 17Die Verbindung zur Datenbank 18

Ein erstes Beispiel 18Tabelle laden und darstellen 19Verknüpfte Tabellen und XML-Daten 21

Dieses Buch 25Die Beispiele dieses Buches 29Konventionen und Symbole 30Tipp 33

1 Visual Studio .NET 35

1.1 Visual Studio .NET und das .NET Framework 361.1.1 Systemvoraussetzungen 371.1.2 Koexistenz mit Visual Basic 6, Upgrade von Projekten 381.1.3 SQL Server und MSDE 381.1.4 IIS-Webserver 39

IIS nachträglich für das .NET Framework einrichten 40

1.2 Die Installation von Visual Studio .NET 411.2.1 MSDE installieren 42

1.3 Die Entwicklungsumgebung von Visual Studio 43Einschränkungen der MSDE aufheben 43

1.3.1 Was bietet die neue IDE? 451.3.2 Der Server-Explorer 491.3.3 Systemressourcen einbinden 501.3.4 Download von zusätzlichen Datenprovidern 50

.NET Framework-Zusätze verwenden 53

1.4 Dokumentation und Selbstdokumentation 54XML-Kommentare verwalten 56

1.5 .NET-Anwendungen debuggen 57

1.6 .NET-Anwendungen kompilieren 59Debug und Release konfigurieren 59

1.6.1 Konfigurationseinstellungen 601.6.2 Kompilierreihenfolge 601.6.3 Vorkompilieren 611.6.4 Kommandozeilencompiler 62

Anwendungen mit dem .NET Framework kompilieren 64

Page 3: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

6 Inhalt

1.7 Alternativen zur Visual Studio .NET-IDE 651.7.1 SharpDevelop 651.7.2 Webmatrix 66

1.8 .NET-Anwendungen installieren 671.8.1 Zielordner festlegen 681.8.2 Setup-Gestaltung 681.8.3 Installation auf Nicht-.NET-Systemen 691.8.4 Benutzerdefinierte Aktionen 69

Benutzereingaben während einer Installation auswerten 70

1.9 Installieren der Beispieldatenbank 711.9.1 SQL Server-Datenbank installieren 721.9.2 MySQL-Datenbank installieren 75

MySQL-Datenbanken und Berechtigungen 75

1.10 Datenbankprojekte 771.10.1 Datenbankverweise 771.10.2 Skripte und Server-Explorer 791.10.3 Tabellen und Sichten 801.10.4 Gespeicherte Prozeduren 81

Debugging im SQL Server zulassen 811.10.5 Trigger 831.10.6 Diagramme 841.10.7 Erstellungsskripte 85

Hinweis auf ORM-Diagramme 851.10.8 Befehlsdateien 861.10.9 Projektverwaltung 86

Skripte zur Datenbankadministration zusammenstellen 88

2 Entwickeln mit .NET 89

2.1 Common Language Runtime 902.1.1 Common Language Infrastructure 922.1.2 Just in Time-Compiler 922.1.3 Sprachintegration 932.1.4 Common Type System 932.1.5 Debugging 932.1.6 Strukturierte Fehlerbehandlung 942.1.7 Speicherverwaltung, Garbage Collector 95

Garbage Collector gezielt aufrufen 972.1.8 Interoperabilität mit COM 97

2.2 Metadaten in .NET 98

2.3 Namensräume und Basisklassen 99

2.4 Assemblies 1002.4.1 Manifest 102

Programmatischer Zugriff auf Assembly-Informationen 103

Page 4: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Inhalt 7

2.5 Sicherheit 1042.5.1 Sicherheit auf Code-Ebene 1042.5.2 Assemblies definieren Sicherheitsbereiche 1052.5.3 Administrieren von Rechten 106

2.6 Versionierung 1072.6.1 Versionierung mit COM 1072.6.2 Versionierung mit Assemblies 108

Neuere Version des .NET Frameworks verwenden 111

3 .NET, Windows und XML-Webdienste (Web Services) 115

3.1 Windows und COM 1173.1.1 Notlösungen 118

3.2 Windows und .NET 1193.2.1 Anforderungen an .NET 119

3.3 Interaktionen über das Internet 121

3.4 Ein Objektmodell für das Internet 122

3.5 XML-Webdienste (Web Services) 122

3.6 Programmierbares Internet 124

3.7 Microsofts .NET-Strategie 1243.7.1 .NET Framework 1253.7.2 .NET-Server 1263.7.3 Visual Studio .NET 1273.7.4 .NET Services 1283.7.5 Software als Service 129

3.8 Plattformunabhängiges .NET 1293.8.1 Rotor (FreeBSD) 1303.8.2 Mono (Linux) 1313.8.3 DotGNU (GNU/Linux) 132

3.9 Eine Infrastruktur für Webdienste 1323.9.1 Web Service Description Language (WSDL) 1333.9.2 UDDI-Verzeichnisse 135

4 Grundlagen der Datenbankbearbeitung 137

4.1 Einführung in Datenbanken 1404.1.1 Datenmodelle 143

4.2 Entwurf relationaler Datenbanken 1474.2.1 Datentabellen und Datenschlüssel 1474.2.2 Tabellenverknüpfungen 1484.2.3 Benennungsregeln 1494.2.4 Referentielle Integrität 1504.2.5 Tabellen-Indizes 1514.2.6 Normalformen 152

Page 5: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

8 Inhalt

4.3 SQL-Grundlagen 1564.3.1 Structured Query Language 157

OSQL für SQL-Anweisungen verwenden 1584.3.2 Schemainformationen 1594.3.3 SELECT 161

Nulldatum des SQL Servers 1694.3.4 UNION 1744.3.5 JOIN 1754.3.6 NULL-Werte 178

Vorgabewerte für Nicht-NULL-Felder 1794.3.7 INSERT 1804.3.8 UPDATE 1814.3.9 DELETE 1824.3.10 Ausblick 183

Duplikate in einer Tabelle finden 183

4.4 XML-Verarbeitung 1844.4.1 Die Herkunft von XML 1844.4.2 Datenabfragen in XML 1864.4.3 XML-Dokumente 1874.4.4 XSL-Transformationen 1914.4.5 XML-Elemente und Attribute 1934.4.6 XML-Dateien und XSD-Schemas 1944.4.7 XML und Namensräume 2004.4.8 XPath-Abfragen 2014.4.9 XPath-Beispiele 2054.4.10 XPath-Richtungsnavigation 2134.4.11 XPath-Abfragen über URL 2224.4.12 XQuery 222

4.5 SQL Server-Datenbanken anlegen und verwalten 228Verbindungen zum SQL Server 229

4.5.1 Datenbank anlegen 230SQL Server zum SQL Server Enterprise Manager hinzufügen 233

4.5.2 Transact-SQL verwenden 2354.5.3 Datenbank aktivieren/deaktivieren 2364.5.4 Datenbanken sichern und wiederherstellen 237

Datenbank dbWürzen aus Datenbanksicherung erstellen 2404.5.5 Benutzer- und Rechteverwaltung 240

Berechtigungen für Datenbankrollen 2474.5.6 Tabellen anlegen 2494.5.7 Indizes anlegen 2514.5.8 Einschränkungen 2524.5.9 Referentielle Integrität 2534.5.10 Diagramme verwenden 2544.5.11 Trigger 2554.5.12 Gespeicherte Prozeduren 257

Page 6: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Inhalt 9

5 ADO.NET und Datenbanken 263

5.1 Einführung in ADO.NET 2635.1.1 Wege nach ADO.NET 265

5.2 Verbindungen zur Datenbank 2685.2.1 Universaler Datenzugriff 2685.2.2 Das asynchrone Modell 2695.2.3 Datenprovider 270

Datenprovider-unabhängiger Code 2725.2.4 Connection-Objekt 274

Datenbankverbindungen in App.config konfigurieren 2775.2.5 Transaktionen 2795.2.6 Command-Objekt 2815.2.7 Mit Gespeicherten Prozeduren arbeiten 2835.2.8 Upgrade von ADO(alt) 285

Upgrade von Visual Basic 6 und Recordsets im DataSet 2885.2.9 ODBC-Datenprovider 2895.2.10 DataReader 290

DataReader und Recordset 291

5.3 Datengebundene Eingabemaske 296Assistenten-Code verwenden 297

5.3.1 DataForm-Assistent 2985.3.2 Das Projekt auf Code-Ebene 305

5.4 DataSet als lokale Datenbank 3155.4.1 Transportable Datenbank 315

5.5 Datenadapter für das DataSet 3175.5.1 DataAdapter 3175.5.2 Datenadapter mit Assistenten konfigurieren 321

5.6 DataSet-Objekt 3335.6.1 DataSet und XML 3375.6.2 DataSet und XML-Dokument 341

5.7 Datenobjekte des DataSets 3435.7.1 DataTable 3435.7.2 DataRow 3535.7.3 DataView 356

5.8 Tabellenverknüpfungen 3635.8.1 DataRelation 3635.8.2 Darstellung verknüpfter Tabellen 3675.8.3 Zugriff auf Detaildaten 369

5.9 Datenauswahl und Datenaktualisierung 3705.9.1 CommandBuilder 3715.9.2 Aktualisieren von Autowerten 373

5.10 Datenbindung und Datennavigation 3755.10.1 BindingContext 3755.10.2 Datenmaske mit Bildern 378

Bilder aus der Datenbank 379

Page 7: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

10 Inhalt

5.11 Hierarchische Daten 3855.11.1 Datengebundenes Treeview 386

5.12 Asynchrone Datenbankanwendungen 4025.12.1 Bedeutung von Transaktionen 4025.12.2 Parallelitätssteuerung in ADO.NET 4055.12.3 Parallelitätsverletzung behandeln 411

6 Datenzugriffsmodule 417

6.1 Datenbankzugriff und Analyse 4186.1.1 Tabellen-Analyseprogramm 419

Datenbankverbindung mit DataLink-Dialog einrichten 4256.1.2 Testmodul für Gespeicherte Prozeduren 438

6.2 Datenzugriffscode (Data Access Application Block) 4456.2.1 Aufbau des Data Access Application Blocks 446

Data Access Application Block einbinden 4466.2.2 Aufruf mit SQL-Anweisung 4496.2.3 Aufruf mit Gespeicherter Prozedur 4536.2.4 Anwendungsbereich 458

7 Serverseitige Datenverarbeitung und Webdienste (Web Services) 461

Webdienstbeispiele installieren oder kopieren 463

7.1 Ein datengebundener Webdienst 465Webprojekte auf entfernten Rechnern einrichten 466

7.1.1 Webdienst benennen 4677.1.2 Namensräume hinzufügen 4677.1.3 Verbindungen zur Datenbank 468

Pfad des virtuellen Verzeichnisses 4697.1.4 Webdienstfunktionen 470

Datenbankzugriff für ASP.NET zulassen 4727.1.5 Erstellen und Testen des Webdienstes 4737.1.6 Webdienst mit Rückgabe eines DataSets 4767.1.7 Webdienst mit DataSet testen 478

Testseiten in Produktivumgebung deaktivieren 479

7.2 Ein Webdienstclient 4807.2.1 Dropdown Gewürzliste 4807.2.2 Einbinden des Webdienstes 482

.vsdisco-Dateien verwenden 4847.2.3 Dropdown an Daten aus dem Webdienst binden 4867.2.4 Webdienst zur Aktualisierung der Datenbank 4887.2.5 Webdienstclient zur Aktualisierung der Datenbank 491

7.3 Daten zwischen Anwendungsebenen übertragen 4997.3.1 Diffgram 500

Page 8: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Inhalt 11

7.4 XML und SQL Server 2000 5067.4.1 OpenXML 5087.4.2 OpenXML und ADO.NET 5147.4.3 FOR XML-Abfragen 515

FOR XML im Query Analyzer 5167.4.4 FOR XML und ADO.NET 530

7.5 Die SQLXML-Erweiterung 5347.5.1 Einrichten von SQLXML 5347.5.2 URL-Aufrufe 5377.5.3 Abfragen an das Datenbankobjekt 5387.5.4 Template-Abfragen 5397.5.5 Schema-Abfragen 5427.5.6 Webdienste aus dem SQL Server 5437.5.7 Ausblick 545

7.6 Datenaustausch mit SQLXML 5457.6.1 Diffgrams als Templates 5457.6.2 Zusammenfassung 548

8 Datenbankgestützte Webanwendungen 549

8.1 Editierbare Listenansicht einer Datenbanktabelle 551Hinweise zur Einrichtung von ASP.NET-Projekten 551

8.1.1 Startseite benennen 5528.1.2 Datenadapter konfigurieren 552

Variante mit Access-Datenbank 5528.1.3 DataGrid hinzufügen und konfigurieren 5548.1.4 Seite laden und Daten anzeigen 557

Datenbankzugriff für das Konto ASPNET 5598.1.5 Paging: Datenausgabe in Ergebnisblöcken 5618.1.6 Zwischenspeichern des DataSets im Session-Objekt 5628.1.7 Daten sortieren 564

Datenbindung aus Code neu zuweisen 5668.1.8 Daten bearbeiten, speichern, löschen 5678.1.9 Daten hinzufügen 5718.1.10 Datenbearbeitung über Login schützen 574

8.2 Datenbankgestützte Loginseite 5748.2.1 Einfache Loginprüfung 575

Authentication und Authorization verwenden 5768.2.2 Loginprüfung mit Datenbankabfrage 5778.2.3 Login aufrufen 5808.2.4 Login auswerten 581

A Links 585

Index 593

Page 9: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Einleitung 13

Einleitung

Mit der Neufassung von Visual Studio auf Basis des .NET Frameworks ist Visual Basic .NET eine echte objektorien-tierte Sprache geworden, die es in Interaktion mit den ADO.NET-Datenobjekten sehr leicht macht, asynchrone Datenbankanwendungen, XML-Webdienste (Web Ser-vices) und datenbasierte ASP.NET-Webanwendungen zu entwickeln.

Der Produktname Visual Basic .NET suggeriert eine Erweiterung odereinen Versionsschritt der weit verbreiteten ProgrammierspracheVisual Basic. Der Zusatz .NET lässt – wie bei anderen Produkten auch– eine starke Ausrichtung auf das Internet vermuten. Auch ADO.NETklingt nach einer speziellen Datenzugriffstechnik für vernetzte Lösun-gen.

Der Titel dieses Buches, Visual Basic .NET und Datenbanken, versprichtAnleitungen, Grundlageninformationen und Beispielcode zum Daten-bankzugriff speziell mit Visual Basic. Wer bereits Visual Basic 6, ADOund MDAC verwendet hat, wird darin eine Darstellung der neuestenActiveX-Datenobjekte und siebzehn neue Techniken zur Verwendungdes Recordsets erwarten.

Um es vorwegzunehmen: Keine dieser Vermutungen trifft wirklich zu,denn weder ist Visual Basic .NET eine Fortschreibung von Visual Basic6, noch beschränkt oder konzentriert sich die Verwendung desnamengebenden .NET-Frameworks auf das Internet, und die in die-sem Buch beschriebene Datenbanktechnologie ADO.NET wird auchmit anderen Programmiersprachen verwendet. Und ganz am Rande:Das Recordset ist abgeschafft.

Die Gemeinsamkeiten von Visual Basic .NET und Visual Basic 6 sindeine im Wesentlichen übereinstimmende Sprachsyntax, der Nameund das Konzept einer benutzerfreundlichen und produktivenArbeitsumgebung. Das ist genug, um sich als Visual Basic 6-Entwick-lerin oder -Entwickler schnell zurechtzufinden, und zu wenig, umohne Hilfestellungen mit Visual Basic .NET die produktive Arbeitsofort fortzusetzen.

Page 10: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

14 Einleitung

Ein Neubeginn mit Visual Basic .NET

Mit Visual Basic .NET beginnt für VB-Programmierer ein neues Zeit-alter, in dem sie sich mit den Basisklassen des umfangreichen .NETFrameworks auseinandersetzen, die ADO.NET-Datenobjekte kennenlernen und die Möglichkeiten echter Objektorientierung sehr baldschätzen lernen werden. Der Neubeginn erfordert es allerdings,Lösungsansätze und Strategien für Datenbankanwendungen zu über-denken und auf der breiten Basis des .NET Frameworks neu zu konzi-pieren. Neueinsteiger haben es hier fraglos einfacher, die neue Platt-form unbelastet zu entdecken.

Wer eine kontinuierliche Fortsetzung der Geschichte von Visual Basicerwartet hat, sieht sich vermutlich getäuscht und um den Wert seinesmit Visual Basic 6 erlernten Wissens gebracht. Der Aufwand, Schrittzu halten, ist nicht zu unterschätzen, denn ohne Basis-Kenntnisse inobjektorientierter Programmierung und ohne ein Verständnis derStruktur und Funktionsweise des .NET Frameworks dürfte es schwersein, erfolgreiche Anwendungen mit Visual Basic .NET zu erstellen.Die Lösung lautet auch hier: learn it now or be left behind.

Update oder Neuschöpfung?

VB6-Entwickler stehen damit vor dem Problem, dass sich existieren-der Datenbankcode nur in den seltensten Fällen sinnvoll nach VisualBasic .NET übertragen lässt. In der Regel wird es angebracht sein, diedatenbankrelevanten Teile der Anwendung ganz neu zu entwickeln,um von den neuen Eigenschaften zu profitieren.

Einige Anwendungsarten, z.B. jene, die einen ständig aktualisiertenDatenstrom benötigen, oder solche, bei denen ein serverseitiger Cur-sor erforderlich ist, lassen sich nicht sinnvoll nach ADO.NET übertra-gen und sollten weiter in VB6 entwickelt und gepflegt werden.

Visual Basic .NET ist eine neue Sprache

Visual Basic .NET stellt kein einfaches Update auf eine neue Versiondar, sondern ist vielmehr eine vollständige, objektorientierte Neufas-sung einer leicht zu erlernenden Programmiersprache für die .NET-Plattform, die – überspitzt formuliert – so entwickelt wurde, dass sichVisual Basic 6-Programmierer leicht darin zurechtfinden können. Sie

Page 11: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Ein Neubeginn mit Visual Basic .NET 15

werden einerseits große Teile der ihnen gewohnten Syntax wieder fin-den und sofort anwenden können, andererseits erfordert .NET dasErlernen neuer Strukturen und neuer Anwendungskonzepte. DieUnterschiede zur Vorversion sind nicht mehr mit dem Begriff »Neue-rungen« zu beschreiben, denn sie greifen tief in die Fundamentesowohl des Betriebssystems als auch der Programmiersprache(n) undder Struktur der damit zu erstellenden Anwendungen ein.

Die Rolle der .NET-Plattform

Die Einführung der .NET-Plattform, die u.a. ein umfassendes »Frame-work« von Basisklassen und Funktionen als Basis aller Programmier-sprachen ist, die Microsoft mit dem Visual Studio anbietet, stellt einenBruch mit den zuvor in Visual Basic favorisierten Technologien COMund ActiveX dar. Die .NET-Plattform besteht aus einer sehr großenBasisklassenbibliothek, einer Sammlung von Compilern für verschie-dene Sprachen zur Erzeugung eines »Zwischencodes« und einemLaufzeitcompiler, der diesen Zwischencode zur Laufzeit in Maschi-nencode umsetzt. Diese Struktur eröffnet mehrere Möglichkeiten:Alle Programmiersprachen, die für das .NET Framework verfügbarsind, benutzen dieselbe Basisklassenbibliothek und haben damit the-oretisch die gleichen Möglichkeiten und das gleiche Leistungsbild.Auch gemischtsprachige Projekte werden damit möglich. Da dieBasisklassenbibliothek einem streng hierarchischen Benennungs-schema folgt, kommen für sie erstellte Programme ohne eine Regis-trierung aus. Statt mit klassischen Installationen können .NET-Anwen-dungen auch nur durch einfaches Kopieren der Dateien ausgeliefertwerden. Da sie nur das .NET Framework benötigen und erst zur Lauf-zeit in Code für die vorhandene Hardware umgesetzt werden, werden.NET-Anwendungen mit dessen (fortgeschrittener) Portierung aufandere Systeme im Prinzip plattformunabhängig und hardwareunab-hängig funktionieren.

Plattformübergreifende Interaktion

Es wäre ein Missverständnis, beim Namen .NET vor allem eine Aus-richtung auf Internetanwendungen zu vermuten. Wesentliche unddirekte Vorteile bringen .NET-Lösungen auch lokal für eine objektori-entierte, konsistente Anwendungsentwicklung. Allein schon die über-fällige Ablösung von den nur schwer zu wartenden COM-Objekten,

Page 12: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

16 Einleitung

der zwingenden Verwendung der Windows-Registry und den Versio-nisierungsproblemen gemeinsam genutzter Systembibliotheken hätteden Aufwand einer neuen Programmplattform gerechtfertigt.

Tatsächlich sind aber auch Internetanwendungen und XML-Web-dienste, die programmatischen Zugriff auf Logik oder Daten sicherüber das Internet ermöglichen, ein wesentlicher Bestandteil von .NET.In der Verbindung mit einer durchgehenden Integration von XML-Technologien lassen sich beliebige Objekte serialisieren und mit demSOAP-Protokoll zwischen Anwendungen und Webdiensten übertra-gen und austauschen.

Bücher zu Visual Basic .NET

Man kann die Bücher, die bereits zu Visual Basic .NET erschienen sind,in drei Gruppen einteilen. Zur ersten gehören Werke, die denUmstieg von Visual Basic 6 erleichtern möchten und zeigen, dass manin Visual Basic .NET auch noch in starker Anlehnung an die Methodenvon Visual Basic 6 programmieren kann. Dabei wird nur soviel von derObjektorientierung und dem .NET Framework erklärt, wie es unbe-dingt erforderlich scheint. Zur zweiten Gruppe gehören Grundlagen-werke und zukünftige Referenztitel, in denen objektorientiertes Pro-grammieren von Grund auf erschlossen wird. Diesen Büchern istgemeinsam, dass sie, um die Leser auf das Niveau der Anwendungs-entwicklung zu führen, auf dem sie sich mit Visual Basic 6 befundenhaben, mindestens den doppelten Umfang eines vergleichbaren Wer-kes zu Visual Basic 6 haben müssen. In der dritten Gruppe, zu derauch dieses Buch gehört, werden ausgewählte Sonderthemen behan-delt, die wie die Datenbankentwicklung zum Teil dramatischen Verän-derungen unterworfen sind. Gleichzeitig spricht diese Gruppe vonBüchern Leserinnen und Leser mit sehr unterschiedlichem Vorwissenan, so dass es notwendig ist, darin die Darstellung von Grundlagenund Anwendungskonzepten mit Beispielen und praktischen Hinwei-sen in ein ausgewogenes Verhältnis zu bringen. Verkürzt gesagt: Eineinzelnes Buch wird nicht ausreichen, um Visual Basic .NET umfas-send zu erschließen. Wenn Sie von Visual Basic 6 umsteigen, emp-fiehlt sich die Zuhilfenahme eines Werkes aus der zweiten Gruppe.

Page 13: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Die neue Datenbanktechnologie ADO.NET 17

Die neue Datenbanktechnologie ADO.NET

ADO(alt) Microsofts Marketingabteilung hat mit dem Namen ADO.NET für dieDatenbanktechnologie in Visual Studio.NET eine zweifelhafte Wahlgetroffen. ADO stand in Visual Basic 6 für ActiveX Data Objects, dieauf der Component Object Model (COM)-Architektur basieren.ADO.NET hat weder etwas mit ActiveX-Technologie noch mit COMzu tun und wäre mit seiner Nähe zu XML vielleicht nach William R.Vaughn ein Kandidat für die Bezeichnung XDO gewesen. Um Ver-wechslungen zu vermeiden, werden in diesem Buch deshalb ActiveXData Objects als ADO(alt), im Gegensatz zu ADO.NET, bezeichnet.

Es war einmal ein Recordset

DataSetEine der grundlegenden Änderungen von ADO(alt) zu ADO.NET istder Wegfall der universellen Tabelle Recordset zu Gunsten des univer-sellen Datencontainers DataSet, der mehrere Tabellen und ihre Ver-knüpfungen aufnehmen kann und alle Qualitäten einer transportab-len Datenbank hat.

Auch wenn das ersatzlose Streichen der zentralen Datenbearbei-tungstechnik aus Visual Basic 6 eine drastische Maßnahme ist, dieeine Neuentwicklung aller vorhandenen Datenzugriffsmodule erfor-dert, lohnt sich der Aufwand, wie Sie bei der Lektüre dieses Buchessicher feststellen werden.

Das Arbeiten mit DataSets heißt zum einen, dass der gesamte Auf-wand entfällt, der notwendig ist, um Daten aus mehreren Datenbank-tabellen zuerst in einem Recordset zusammenzufassen, um sie danachin der Anwendung wieder aufzuschlüsseln und über ein anderesRecordset gezielt zu aktualisieren. Zum anderen lässt sich ein DataSetals eine Kopie oder ein Teilauszug der originalen Datenbank in derAnwendung verstehen. ADO.NET verwendet Hilfsobjekte wie z.B.Datenadapter, die für den Transport der Daten aus der Datenbank indas DataSet und zurück sorgen. Folgerichtig ist nur noch dann eineVerbindung zur Datenbank notwendig, wenn Daten geladen oderaktualisiert werden.

Page 14: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

18 Einleitung

Die Verbindung zur Datenbank

asynchron Womit die zweite, fundamentale Änderung genannt wäre: ADO.NET-Anwendungen verwenden eine Datenbank asynchron, d.h., sie sindnur noch für den möglichst kurzen Zeitraum, den eine Lese- oderSchreibaktion dauern sollte, mit der Datenbank verbunden.

In ADO.NET-Anwendungen werden, anders als in ADO(alt), immererst alle zu verarbeitenden Daten in das DataSet der Clientanwen-dung geladen, wo die Datenverarbeitung vollständig getrennt von derDatenbank stattfindet. Die Entsprechung in ADO(alt) wäre ein client-seitiger Cursor, dem in der Regel zur Steigerung der Leistungsfähigkeitein serverseitiger Cursor vorgezogen wird, um möglichst wenig Datenzum Client zu übertragen und möglichst viel Datenbanklogik vomDatenbankserver ausführen zu lassen. Mit dem asynchronen Modellvon ADO.NET entfällt diese Option, und der Einsatz der klassischenserverseitigen Datenverarbeitung reduziert sich auf die Datenbereit-stellung und das Ausführen von Gespeicherten Prozeduren.

Ein einmal gefülltes DataSet behält auch, nachdem seine Daten ineiner Anwendung bearbeitet wurden, immer einen Bezug zu seinemOriginalzustand nach dem Laden der Daten. Alle Änderungen, Hinzu-fügungen und Löschungen werden gekennzeichnet und erlauben es,zu einem beliebigen späteren Zeitpunkt ausschließlich die Verände-rungen in die Datenbank zu übertragen. In diesem Moment lässt sichsogar feststellen, ob ein anderer Client dieselben Daten ebenfalls ver-ändert hat, um beide Anwender über die Datenkonkurrenz zu infor-mieren.

Ein erstes Beispiel

Im Folgenden soll ein kleines Beispiel einen ersten Eindruck von denObjekten und Methoden vermitteln, die für einen asynchronenDatenbankzugriff mit ADO.NET verwendet werden. Dabei werdenmehrere Datenbanktabellen in der Listenansicht eines DataGrids dar-gestellt.

Page 15: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Ein erstes Beispiel 19

Tabelle laden und darstellen

Das folgende Beispiel finden Sie auf der beiliegenden CD-ROM imVerzeichnis \Einleitung\dbEinleitung.

Beispiel dbEinleitung

Legen Sie in Visual Studio .NET ein Projekt vom Typ Windows-Anwendung an, das Sie dbEinleitung nennen. Ziehen Sie in der Ent-wurfsansicht der Maske Form1 aus dem Abschnitt Windows Forms derToolbox ein DataGrid auf die Maske.

Wechseln Sie über das Menü Ansicht • Code in die Code-Ansicht.Wählen Sie aus dem linken Codenavigations-Dropdown Basisklas-senereignisse, dann aus dem rechten Load, um die Ereignisprozedurfür das Laden von Form1 anzulegen, in die der gesamte Code diesesBeispiels geschrieben wird.

Das Beispiel verwendet die Access-Datenbank dbWürzen.mdb, die Sieauf der CD-ROM im Verzeichnis \Datenbank finden. Kopieren Siediese Datei in das \bin-Unterverzeichnis des Projektverzeichnisses,das in der Voreinstellung den Pfad %userprofile%\Eigene Dateien\Visual Studio-Projekte\dbEinleitung hat.

Verbindung zur Datenbank

Die Verbindung zur Datenbank wird über ein Connection-Objekt her-gestellt, das dem gleichbenannten Objekt in Visual Basic 6 ähnlich istund die gleiche Syntax für die Verbindungszeichenketten verwendet.Im Beispiel wird Access als OleDB-Datenbank angesprochen, weshalbdie OleDb-Variante des Connection-Objektes erforderlich ist. Da dieDatenbank im Projektausgabeverzeichnis \bin liegt, genügt dieAngabe des Dateinamens in der Verbindungszeichenkette (sieheListing 0.1).

Datenadapter

Das Füllen einer Datentabelle aus einer OleDbConnection erfordertebenfalls die OleDB-Variante des Datenadapters. Der OleDbData-Adapter wird mit einer SQL-Anweisung für die Datenauswahl und einangegebenes Connection-Objekt erstellt. Im Beispiel werden Datenaus der Tabelle tblGewürze ausgewählt.

Page 16: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

20 Einleitung

Datentabelle füllen

Der Vorgang, die Daten zu laden, erfolgt allein durch den Aufruf derFill-Methode des Datenadapters, die mit der Datentabelle als Argu-ment aufgerufen wird.

Daten anzeigen

Die Datentabelle, die jetzt Daten enthält, wird dem DataGrid1 alsDataSource-Eigenschaft zugewiesen. Als DataMember genügt derName der Datentabelle, den das Objekt DataTable als Textwert trägt.

Listing 0.1 Laden und Darstellen einer Tabelle

Private Sub Form1_Load( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Die Verbindung zur Datenbank Dim _conn As New OleDb.OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=dbWürzen.mdb;" & _ "User ID=Admin;") ' Die Datenadapter Dim _daGewürze As New OleDb.OleDbDataAdapter( _ "SELECT pkGewürz," & _ " Gewürzname,Gattung " & _ "FROM tblGewürze", _

_conn) ' Eine Datentabelle erzeugen Dim _dt As New DataTable() ' DataSet über Datenadapter füllen _daGewürze.Fill(_dt) _conn.Close() ' DataSet im DataGrid anzeigen DataGrid1.DataSource= _dt DataGrid1.DataMember= _dt.ToStringEnd Sub

Mit dem Start der Anwendung über (F5) wird die Datentabelle überden Datenadapter gefüllt und im DataGrid angezeigt.

Page 17: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Ein erstes Beispiel 21

Der gezeigte Weg ist nicht aufwändiger als eine funktionsgleicheLösung mit einem ADO(alt)-Recordset.

Verknüpfte Tabellen und XML-Daten

In einer erweiterten Version des Beispiels werden mehrere Tabellen indas DataSet übertragen und dort wie in einer Datenbank verknüpft.Diese Aufgabe liegt außerhalb der Fähigkeiten einer Recordset-Verar-beitung, ist in ADO.NET jedoch mit einer geringfügigen Erweiterungdes Codes möglich.

Definieren Sie einen zweiten Datenadapter mit einer weiteren SQL-Anweisung, im Beispiel stammen die Daten aus der Tabelle tblBil-der, die in der Datenbank mit der Tabelle tblGewürze über deren Pri-märschlüssel verknüpft ist.

Tabellen im DataSet

Ändern Sie den Aufruf der Fill-Methode dahin, dass anstelle derDatentabelle ein DataSet-Objekt gefüllt wird, das als zusätzlichesArgument einen Namen für die zu erstellende Tabelle erwartet. Fügen

Abbildung 0.1 Darstellung einer Datentabelle im DataGrid

Page 18: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

22 Einleitung

Sie den Aufruf eines zweiten Datenadapters hinzu, dessen Fill-Methode auf das gleiche DataSet angewendet wird.

Verknüpfung

Das DataSet enthält an dieser Stelle zwei benannte Datentabellen, fürdie eine Verknüpfung wie in einer Datenbank definiert werden kann.Es beinhaltet zudem eine Auflistung der Relations genannten Tabel-lenverknüpfungen, der Sie durch Anwendung der Add-Methode einneues DataRelation-Objekt für die beiden Tabellen hinzufügen kön-nen. Zur Erzeugung der Tabellenverknüpfung sind lediglich die zu ver-knüpfenden Spaltennamen, im Beispiel tblGewürze.pkGewürz undtblBilder.fkGewürz, sowie ein Name für die Verknüpfung erforder-lich.

Das DataGrid akzeptiert auch ein DataSet als DataSource-Eigen-schaft, als DataMember wird einer der beiden Tabellennamen angege-ben, die aus der Tables-Auflistung des DataSets verfügbar sind.

XML-Daten

Um die Verknüpfung der Daten in der Anzeige zu sehen, kann einTextbox-Steuerelement verwendet werden, in dem die Daten desDataSets als XML-Daten ausgegeben werden. Ziehen Sie dazu in derEntwurfsansicht von Form1 eine Textbox aus der Toolbar auf dieMaske. Setzen Sie im Eigenschaftenfenster die Eigenschaft Multilineauf True und positionieren Sie die Textbox1 neben dem DataGrid1auf der Maske.

Die XML-Daten werden in einem Schritt mit Hilfe der GetXml-Methode des DataSets in die Textbox übertragen.

Fügen Sie vor der Anzeige der XML-Daten eine Zuweisung des WertesTrue an die Nested-Eigenschaft der DataRelation im DataSet ein, umeine geschachtelte Darstellung der XML-Daten zu erhalten.

Listing 0.2 Tabellen verknüpfen und XML-Daten anzeigen

Private Sub Form1_Load( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load

Page 19: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Ein erstes Beispiel 23

' Die Verbindung zur Datenbank Dim _conn As New OleDb.OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=dbWürzen.mdb;" & _ "User ID=Admin;") ' Die Datenadapter Dim _daGewürze As New OleDb.OleDbDataAdapter( _ "SELECT pkGewürz," & _ " Gewürzname,Gattung " & _ "FROM tblGewürze", _

_conn) Dim _daBilder As New OleDb.OleDbDataAdapter( _ "SELECT fkGewürz," & _ " Bildname " & _ "FROM tblBilder", _

_conn) ' Das DataSet erzeugen Dim _ds As New DataSet() ' DataSet über Datenadapter füllen _daGewürze.Fill(_ds, "Gewürze") _daBilder.Fill(_ds, "Bilder") _conn.Close() ' Tabellenbeziehung einrichten _ds.Relations.Add( _ New DataRelation( _ "relGewürzeBilder", _ _ds.Tables("Gewürze").Columns("pkGewürz"), _ _ds.Tables("Bilder").Columns("fkGewürz"))) ' Tabellenbeziehung geschachtelt darstellen _ds.Relations.Item(0).Nested = True ' DataSet im DataGrid anzeigen DataGrid1.DataSource= _ds DataGrid1.DataMember= _ds.Tables("Gewürze").ToString ' DataSet als XML anzeigen

TextBox1.Text = _ds.GetXmlEnd Sub

Starten Sie die Anwendung erneut. Sie sehen neben der DatentabelleGewürze in der Textbox den XML-Code des dazugehörigen DataSetsangezeigt, der in jedem Abschnitt Gewürze den entsprechendenAbschnitt aus Bilder enthält.

Page 20: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

24 Einleitung

In der Tabellenansicht sehen Sie im Kopf jeder Zeile einen Datenkno-ten, der beim Klick einen Link auf die in der Tabelle Bilder verknüpftenDaten freigibt. Folgen Sie diesem Link, wird der entsprechendeDatensatz der Tabelle Bilder im DataGrid angezeigt.

Der Aufwand, der in diesem Beispiel notwendig war, um Tabellen zuübertragen, sie zu verknüpfen und in verschiedenen Modi auszuge-ben, ist minimal und erfordert keinerlei Datenschleifen und keinedirekte Auswertung der Tabelleninhalte.

Die gesamte Darstellung der Inhalte findet statt, nachdem die Verbin-dung zur Datenbank schon wieder geschlossen ist.

Nach einer Veränderung der Daten im DataSet könnte ein Aktualisie-ren der Datenbank, für jede Tabelle getrennt, allein über den Aufrufder Update-Methode des Datenadapters erfolgen.

Abbildung 0.2 Darstellung verknüpfter Tabellen im DataGrid und als XML-Daten-menge

Page 21: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Dieses Buch 25

Dieses Buch

Dieses Buch ist in der Absicht geschrieben, den Einstieg in die Daten-bankprogrammierung mit Visual Basic .NET zu erleichtern und überdie Hürden und Fallstricke hinweg zu helfen, die der Autor bei derBeschäftigung mit Visual Studio .NET seit der Beta 1 selbst erfahrenhat. Anhand von praktischen Beispielen und wieder verwendbaremCode soll es Sie in die Programmierung von Datenbankanwendungenmit Visual Basic .NET einführen.

Sie lernen die Leistungsfähigkeit und Vorteile der neuen Datenbank-objekte in ADO.NET und ihre Bedeutung für neue Anwendungskon-zepte kennen und erfahren Konzepte und Techniken, wie Sie mitVisual Basic .NET Datenbanken nutzen, erstellen, ändern, Daten dar-stellen, bearbeiten und austauschen.

Kapitel 1 stellt die neue Entwicklungsumgebung von Visual Studio.NET vor.

� Es werden Hinweise zur Installation und Einrichtung von VisualStudio .NET gegeben sowie einige zusätzliche Datenprovider fürADO.NET vorgestellt, die durch Download ergänzt werden kön-nen.

� Es gibt einen Überblick über die wichtigsten Bestandteile undFunktionen zum Erstellen, Debuggen, Verwalten und Ausliefernvon Anwendungen für das .NET Framework.

� Die Einrichtung der Desktop-Version von SQL Server 2000 (MSDE)und des IIS-Webservers wird beschrieben sowie die manuelleInstallation der Beispieldatenbank dbWürzen auf einem SQL Serverund in einer MySQL-Datenbank.

Kapitel 2 stellt das neue Visual Basic in den größeren Zusammenhangdes .NET Frameworks und erklärt seine Bestandteile.

� Sie erfahren, was die Common Language Runtime und was eineAssembly ist, wie Visual Basic .NET mit dem .NET Framework inter-agiert und wie Komponenten versioniert werden.

� Es werden Hinweise zum Sicherheitskonzept und der Speicherver-waltung des .NET Frameworks gegeben.

Page 22: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

26 Einleitung

Kapitel 3 zeigt den Zusammenhang von .NET Framework, XML-Web-diensten (Web Services) und dem programmierbaren Internet in der.NET-Strategie von Microsoft, um die Hintergründe der grundlegen-den Neuerungen deutlich zu machen.

� Es erläutert, warum Microsoft entschieden hat, die COM-Techno-logie nicht weiter zu verfolgen und stattdessen das .NET Frame-work als Grundlage zukünftiger Windows-Versionen zu verwen-den.

� Es wird gezeigt, was es mit dem Schlagwort vom programmierbarenInternet auf sich hat und welche Rolle XML-Webdienste in diesemKonzept spielen.

� Sie erfahren, wie mit Hilfe der Common Language Infrastructure.NET-Code auch auf anderen Plattformen kompiliert und ausge-führt werden kann und welche Initiativen es dazu gibt.

Kapitel 4 stellt Grundlagen der Datenbankbearbeitung mit relationa-len Datenbanken und hierarchischen Datenmengen in XML dar.

� Es wird der Entwurf relationaler Datenbanken unter der Berück-sichtigung der klassischen Normalformen gezeigt.

� Ein eigener Abschnitt führt anhand von Beispielen in die Grund-lagen von SQL-Anweisungen ein.

� Da mit ADO.NET neben dem klassischen SQL auch XML-Technolo-gien bei der Entwicklung datenbankgestützter Anwendungen zumEinsatz kommen, wird erläutert, wie XML-Daten und XML-Daten-schemas aufgebaut sind. Ihre Verarbeitung wird anhand der XPath-Navigation und mit XQuery-Abfragen demonstriert.

� Die Darstellung der Grundlagen wird ergänzt durch Anleitungenzur Verwaltung und Administration von SQL Server-Datenbankenmit dem SQL Server Enterprise Manager und über SQL-Skripte.

Kapitel 5 erklärt das objektbasierte Datenbankmodell von ADO.NETausführlich anhand praxisnaher Aufgabenstellungen und Themen.

� Es wird ein Überblick über die Objekte gegeben, die in ADO.NETverwendet werden, und ihr Zusammenhang an einem vollständi-gen Beispiel einer datengebundenen Maske erläutert.

Page 23: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Dieses Buch 27

� Das neue und zentrale Datenbankobjekt DataSet wird ausführlicherläutert, und seine Unterobjekte werden einzeln vorgestellt. DieObjekte werden durch Auflistungen ihrer Eigenschaften undMethoden direkt vergleichbar gemacht, um sie in Anwendungengezielt einsetzen zu können.

� Es werden fortgeschrittene Themen wie die Darstellung hierarchi-scher Daten und die Verarbeitung von Bildern in der Datenbankbehandelt.

� Es geht auch um die Aufgaben zur Aktualisierung und zur Behand-lung von Datenkonkurrenz, die sich mit dem asynchronen Modellvon ADO.NET neu stellen.

Kapitel 6 stellt Codemodule vor, mit deren Hilfe Sie den Datenzugriffin ADO.NET-Anwendungen vereinfachen und vereinheitlichen kön-nen.

� Es erläutert Hilfsanwendungen zur Analyse von Datenbanktabellenund von Gespeicherten Prozeduren.

� Es gibt eine Einführung in den Data Access Application Block, mitdem Microsoft optimierten Datenzugriffscode als .NET-Kompo-nente veröffentlicht hat.

Kapitel 7 behandelt die serverseitige Datenverarbeitung verteilterKomponenten.

� Es wird gezeigt, wie ASP.NET-Webdienste zur Anzeige und zurAktualisierung von Datenbankinhalten erstellt und genutzt werden.

� Es behandelt die XML-Verarbeitung im SQL Server 2000 und dieVeröffentlichung von Webdiensten aus dem SQL Server.

� Der Datenaustausch zwischen den Ebenen einer Anwendung wirderläutert und das dabei verwendete Diffgram-Format des DataSetsdargestellt.

Page 24: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

28 Einleitung

Kapitel 8 beschäftigt sich mit datenbankgestützten Webanwendun-gen.

� Es führt in die Anwendung der ADO.NET-Programmierung aufASP.NET-Webanwendungen ein und gibt Hinweise zur Umsetzungvon Webprojekten und verteilten Anwendungen.

Das Buch ist somit in mehrere Teile untergliedert, die unterschiedli-chen Leserbedürfnissen bzw. -perspektiven Rechnung tragen. DieKapitel 1 bis 3 eignen sich als Einführung und Überblick über die Tech-nologie und ermöglichen damit eine Einschätzung des Aufwands, vonVisual Basic 6 auf Visual Basic .NET umzustellen. Kapitel 4 und 5 sinddie Lernkapitel für Programmierer, in denen die Datenbankgrundla-gen und die neue Datenbanktechnologie ADO.NET an vielen Beispie-len vermittelt werden. Kapitel 6 vertieft die Thematik für fortgeschrit-tene Anwender, während Kapitel 7 und 8 erweiterte Projekte undverteilte Anwendungen darstellen.

Systemvoraussetzungen und Installation

Um die Beispiele in diesem Buch nachvollziehen zu können, mussmindestens das .NET Framework, besser natürlich Visual Studio .NETinstalliert werden. Da das .NET Framework den Compiler für VisualBasic .NET vbc.exe enthält, können damit vollständige Anwendungenallein aus dem Quellcode und den Beispielen dieses Buches kompi-liert werden. Die Beispielprojekte in diesem Buch basieren auf demFunktionsumfang der Professional-Ausgabe von Visual Studio .NETund funktionieren mit dem .NET Framework 1.0 mit Servicepack 2.

Sie finden das .NET Framework und das .NET Framework SDK sowiedas aktuelle Servicepack auf der beiliegenden CD-ROM im Verzeich-nis \DotNETFramework.

Bei der Installation von Visual Studio .NET oder des .NET FrameworkSDK haben Sie die Option, eine Desktopversion MSDE des SQL Ser-ver 2000 einzurichten, die als Datenbankserver für die Beispiele indiesem Buch völlig ausreicht.

Bitte beachten Sie, dass die ausführbaren Anwendungsdateien derBeispielprojekte, die sich im Projektausgabeverzeichnis \bin einer Bei-spielanwendung befinden, bezüglich der installierten Version des.NET Frameworks versionsgebunden sind. Sie müssen nach Anwen-

Page 25: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Dieses Buch 29

dung eines neueren Servicepacks oder einer Aktualisierung desFrameworks neu kompiliert werden.

Die Beispiele dieses Buches

Datenbank dbWürzen

Die Beispieldatenbank für die Beispiele in diesem Buch heißt dbWür-zen und enthält eine Sammlung von Gewürzen mit Informationen zurGattung, Herkunft und den Mischungen, in denen sie verwendet wer-den. Die Datenbank ist sowohl als SQL Server-Datenbank dbWürzenals auch als Access-Datenbank dbWürzen.mdb und als allgemeinesSQL-Datenbankskript auf der CD-ROM im Verzeichnis \Datenbank zufinden. Die Einrichtung der Datenbank per Datenbankskript wird inAbschnitt 1.9, »Installieren der Beispieldatenbank«, beschrieben. Diemeisten Beispiele in diesem Buch funktionieren sowohl mit derAccess- als auch mit der SQL Server-Datenbank. Einige Beispiele sindjedoch ausschließlich mit einer SQL Server-Datenbank zu nutzen.

Auf der beiliegenden CD-ROM finden Sie im Verzeichnis \Installationdrei Installationsprogramme, mit denen die BeispieldatenbankdbWürzen und die Beispiele dieses Buches, getrennt nach Windows-und Webanwendungen, einschließlich Quellcode installiert und bisauf die Datenbank auch wieder deinstalliert werden können.

� dbVBNETAnwendungen.msiInstalliert die Windows-Beispielanwendungen aus den Kapiteln 1,4, 5 und 6.

Die Installation setzt voraus, dass zuvor Visual Studio .NET oder das.NET Framework sowie ein SQL Server oder eine MSDE installiert wur-den. Der Datenbankserver sollte zum Zeitpunkt der Installation bereitslaufen.

� dbVBNETWebAnwendungen.msiInstalliert die Webdienste und Webanwendungen aus den Kapiteln7 und 8.

Die Installation setzt voraus, dass Sie einen lokalen IIS-Webserver undVisual Studio .NET oder das .NET Framework installiert haben. DasInstallationsprogramm legt virtuelle Verzeichnisse für die Webdienst-beispiele aus Kapitel 7 und die Webanwendungsbeispiele aus Kapitel 8an.

Page 26: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

30 Einleitung

� dbWürzenMSSQL.msiInstalliert die SQL Server-Datenbank dbWürzen, die in den Beispie-len verwendet wird.

Während der Installation werden Sie nach dem Namen eines SQL Ser-vers gefragt, auf den Sie Zugriff mit Integrierter Sicherheit haben. DerServername eines SQL Servers auf einem Einzelrechner ist entweder(local) oder, wenn Sie eine MSDE benutzen, (local)\NetSDK oder(local)\VSdotNET.

Startmenü Die Installationsprogramme fügen dem Startmenü unter Programmeden Punkt VB.NET und Datenbanken hinzu, der nach Kapiteln sor-tierte Verknüpfungen zu den Visual Studio .NET-Beispielprojektenund zu den ausführbaren fertigen Beispielanwendungen enthält.

Beispielcode Auf der beiliegenden CD-ROM finden Sie in den mit Kapitelnamenbenannten Unterverzeichnissen die beschriebenen Beispielprojekteund alle Listings aus den Anleitungen innerhalb der einzelnen Kapitel.Die Beispielprojekte können auch ohne die Verwendung des Installa-tionsprogrammes durch Kopieren der entsprechenden Verzeichnissevon der beiliegenden CD-ROM verwendet werden. Der dabei über-tragene Schreibschutz sollte zurückgesetzt werden. Die Projekte sindvollständig und enthalten im Unterverzeichnis \bin jeweils die aus-führbare *.exe-Datei, sofern es sich nicht um eines der Webprojektehandelt.

Von der Startseite index.html der beiliegenden CD-ROM aus habenSie direkten Zugriff auf alle Beispieldateien und Programmlistings.Eventuell notwendige Aktualisierungen finden Sie mit Ihrer persönli-chen Registriernummer am Ende des Buches auf der Website vonGalileo Press unter: http://www.galileocomputing.de.

Konventionen und Symbole

Programmcode und Listings

Soweit es zum Verständnis notwendig ist, wird im Text der dazugehö-rige Programmcode dargestellt. An den Stellen, an denen satztech-nisch ein Umbruch erforderlich ist, werden die Zeilenfortsetzungszei-chen _ und & _ eingesetzt, die auch von Visual Basic .NET verwendetwerden. Damit ist es unproblematisch, den Programmcode auchmanuell zu übertragen.

Page 27: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Dieses Buch 31

Konventionen zur Objektbenennung

In diesem Buch werden Objekte in Anlehnung an die Konventionenbenannt, die Greg Reddick für Visual Basic-Programme aufgestellt hat.Einen Link zu den Reddick VBA Naming Conventions (RVBA) finden Siein der Linkliste im Anhang. An derselben Stelle gibt es auch einen Ver-weis auf die Arbeitsversion der Reddick .NET Conventions für VB.NET-Objekte.

In der Absicht, Programme leichter lesbar zu machen, ermöglichen esdiese Benennungsregeln, Objektnamen so aufzubauen, dass daranInformationen über die Art, den Geltungsbereich und die Herkunfteines Objektes ablesbar werden.

Die Regeln folgen der so genannten Ungarischen Notation, nach derObjekte einheitlich benannt werden in der Form:

[Präfix]Tag[BasisObjektName[Suffix]]

Die BasisObjektNamen werden wie in Pascal mit großen Buchstabenam Anfang jeden Wortes geschrieben, wie z.B. in GewürzListe.

Abbildung 0.3 Zugriff auf Beispiele und Listings auf der CD-ROM dieses Buches

Page 28: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

32 Einleitung

Ergänzt werden diese Namen durch einen kurzen, vorangestelltenTag, der den Datentyp des Objektes angeben sollte, z.B. strGewürz-Name für eine Zeichenkette (String) oder intGewürz für einen Integer-Wert.

Die aus Tag und BasisObjektName zusammengesetzte Benennungerhält einen Präfix, der den Geltungsbereich des Objektes angibt:

� g für öffentliche, als public deklarierte, globale Variablen, z.B.gintGewürze

� m für modulweite, als private deklarierte, gültige Variablen, z.B.mstrGattung

� s für als static deklarierte Variablen, z.B. sintAufrufe

Ohne Präfix bleiben nur prozedurweit gültige Objekte.

In diesem Buch werden allgemeine, in ihrem Geltungsbereich auf Pro-zeduren beschränkte Objekte in der Regel nur mit dem Tag und demPräfix _ benannt, z.B. _dt für eine Datentabelle.

Geltungsbereich von VariablenMit Visual Basic .NET werden neue, auf Prozedurabschnitte begrenzteGeltungsbereiche von Variablen eingeführt. Eine innerhalb einerSchleife oder einer strukturierten Fehlerbehandlung deklarierte Vari-able ist nur dort gültig.

Dim arrNamen as String()Dim _str as StringFor each _str in arrNamen Dim _int as Integer _int = _str.Length Console.writeLine(_int)Next

Die verborgene Variable _int belegt nur für die Dauer der Schleifen-auswertung Ressourcen und steht außerhalb der Schleife nicht zurVerfügung. Dort kann allerdings auch keine weitere Variable mit demNamen _int deklariert werden. Auf die fehlerhafte Verwendungverborgener Variablen werden Sie bereits zur Entwurfszeit von VisualStudio hingewiesen.

Page 29: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Dieses Buch 33

Symbole

Hinweise warnen vor bekannten Missverständnissen und sollen derVermeidung häufig vorkommender Probleme dienen. Ebenso kann essich um Verweise auf weiterführende Informationen handeln.

Tipp

In den Hauptkapiteln finden Sie am Ende wichtiger Abschnitte grauunterlegte Anleitungen, in denen praktische Hinweise und Anlei-tungen zur Konfiguration und Einrichtung von Visual Studio .NETund den verwendeten Serverdiensten gegeben werden.

Page 30: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 343

' Einzelnen Datensatz anzeigen MessageBox.Show(dtGewürze.Rows.Item(12). _ Item("Gewürzname").ToString)End Sub

Das XMLDocument enthält eine Eigenschaft DataSet, die eine rela-tionale Darstellung seiner Inhalte ermöglicht. XML-Daten werden imXML-Dokument mit Hilfe ihres abgeleiteten Schemas ausgewertet,und können über das relationale Modell des DataSets z.B. als Daten-zeilen angesprochen werden. Im Beispiel wird der Inhalt des Data-Sets erneut in XML gewandelt und in derTextbox angezeigt.

5.7 Datenobjekte des DataSets

5.7.1 DataTable

Die DataTable ist ein einfaches Objekt, das eine Datenquelle dar-stellt. Es enthält keine Information über die Herkunft der Daten, mitdenen es gefüllt ist. Eine DataTable kann alleine oder innerhalb einesDataSets verwendet werden.

Abbildung 5.29 XML-Daten aus einem synchronisierten DataSet

Page 31: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

344 ADO.NET und Datenbanken

Auslesen vonÄnderungen über

GetChanges()

DataTables überwachen wie DataSets Änderungen an den gelade-nen Daten bzw. sind Bestandteil der Änderungsverfolgung von Data-Sets. Geänderte Daten können über die Methode GetChanges alseigene DataTable ausgelesen werden. Dieser Mechanismus wird bei-spielsweise über einen DataAdapter ausgelöst, um separate Aktionenfür das Aktualisieren von Daten zu definieren.

Eine DataTable kann manuell erzeugt werden, wird aber auch durchdie Fill-Methode des DataAdapters in einem DataSet automatischerstellt und gefüllt. Sie dient der Bearbeitung, Navigation, Sortierungund Filterung von Daten im Speicher sowie der Erstellung von Sich-ten.

DataTable programmatisch erzeugen

Es ist sehr einfach, programmatisch eine DataTable anzulegen und inein DataSet einzufügen.

Beispiel dtKlimata Das folgende Beispiel ist ein Projekt vom Typ Konsolenanwendung,das ohne Maske und ohne Datenbankverbindung auskommt, da einDataSet und eine DataTable programmatisch erstellt werden. Sie fin-den das Beispielprojekt auf der beiliegenden CD-ROM im Verzeichnis\Kapitel05\dtKlimata.

In diesem Beispiel wird eine Datentabelle dtKlimata mit drei Daten-spalten pkKlima, Klimaname und Temperatur angelegt und in einDataSet eingefügt. Daten und Schema des DataSets werden anschlie-ßend als XML-Daten im Anwendungsverzeichnis ausgegeben.

Listing 5.29 Programmatisch erzeugte DataTable im DataSet

Dim dsDataSet As DataSetDim dtKlimata As DataTableSub Main() ' DataSet erzeugen Dim dsDataSet As DataSet dsDataSet = New DataSet() ' DataTable erzeugen Dim dtKlimata As DataTable dtKlimata = New DataTable("tblKlimata") ' Tabellenspalte mit Primärschlüssel definieren Dim dcNeu As DataColumn dcNeu = New DataColumn()

Page 32: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 345

dcNeu.ColumnName = "pkKlima" dcNeu.DataType = Type.GetType("System.Int32") ' Primärschlüsselwerte automatisch erzeugen dcNeu.AutoIncrement = True dcNeu.AutoIncrementSeed = 1 dcNeu.AutoIncrementStep = 1 dcNeu.AllowDBNull = False ' Tabellenspalte in die Tabelle einfügen dtKlimata.Columns.Add(dcNeu) ' Tabellenspalte einem Primärschlüssel-Array ' hinzufügen Dim arrPrimaryKey(0) As DataColumn arrPrimaryKey(0) = dcNeu ' Primärschlüssel in der Tabelle setzen

dtKlimata.PrimaryKey = arrPrimaryKey ' Tabellenspalte für den Namen definieren dcNeu = New DataColumn() dcNeu.ColumnName = "Klimaname" dcNeu.DataType = Type.GetType("System.String") ' Tabellenspalte in die Tabelle einfügen dtKlimata.Columns.Add(dcNeu) ' Tabellenspalte für die Beschreibung definieren dcNeu = New DataColumn() dcNeu.ColumnName = "Temperatur" dcNeu.DataType = Type.GetType("System.Int32") ' Tabellenspalte in die Tabelle einfügen dtKlimata.Columns.Add(dcNeu) 'Tabelle dem DataSet hinzufügen dsDataSet.Tables.Add(dtKlimata) ' DataSet und Schema als XML speichern dsDataSet.WriteXmlSchema("dtKlimataSchema.xml") dsDataSet.WriteXml("dtKlimata.xml")End Sub

Primärschlüssel-Array

Zunächst wird eine neue Datentabelle tblKlimata erzeugt, der eineSpalte pkKlima hinzugefügt wird, die Primärschlüssel werden soll.Jede Spalte, die den Primärschlüssel aufnehmen soll, muss gleichzeitigals Array von Datenspalten angelegt werden, das die Datentabelleüber die Eigenschaft PrimaryKey aufnimmt. Außer der Schlüsselspaltewerden noch die Datenspalten Klimaname und Temperatur vom TypZeichenkette und Integer hinzugefügt.

Page 33: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

346 ADO.NET und Datenbanken

Um die neue DataTable auszuwerten, wird sie in ein neues DataSeteingefügt, dessen Schema und Inhalte anschließend im XML-Formatausgegeben werden.

Testen Sie das Beispiel und öffnen Sie danach die Datei dtKlimata-Schema.xml im Projektausgabeverzeichnis \bin.

Das Schema enthält die Spaltendefinitionen und den Primärschlüsselder programmatisch erzeugten Datentabelle dtKlimata.

DataTable-Eigenschaften

Das Objekt DataTable hat folgende Eigenschaften:

Abbildung 5.30 Schema der DataTable dtKlimata im DataSet

Name Beschreibung

CaseSensitive Setzt oder liest einen Booleschen Wert, der festlegt, ob ein Zeichenkettenvergleich schreibungssensitiv ausgeführt wird. Wenn die Tabelle Teil eines DataSets ist, übernimmt sie diese Eigenschaft vom DataSet. Bei der programmati-schen Erzeugung einer DataTable wird dieser Wert mit False vorgegeben.

Tabelle 5.16 DataTable-Eigenschaften

Page 34: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 347

ChildRelations Gibt alle Detaildatenbeziehungen der Tabelle als Auflistung vom Typ DataRelationCollection zurück oder Nothing, wenn keine Detaildatenbeziehungen vorhanden sind

Columns Gibt eine Auflistung der Spalten der Tabelle als Auflistung vom Typ DataColumnCollection zurück oder Nothing, wenn keine Spalten vorhanden sind

Constraints Gibt eine Auflistung der Einschränkungen der Tabelle als Auflistung vom Typ ConstraintCollection zurück oder Nothing, wenn keine Einschränkungen vorhanden sind

DataSet Gibt das DataSet, zu dem die Tabelle gehört, als Objekt zurück

DefaultView Gibt ein DataView-Objekt zurück, das eine benutzerdefi-nierte, sortierte und gefilterte Sicht auf die Tabelle oder einen einzelnen Datensatz sein kann

DisplayExpres-sion

Setzt oder liest eine Zeichenkette, die benutzt werden kann, die Tabelle in der Benutzeroberfläche zu kennzeich-nen

ExtendedProper-ties

Gibt eine Auflistung der benutzerdefinierten Informationen als PropertyCollection zurück. Die Eigenschaft besitzt eine Methode Add, mit der ExtendedProperties als Zei-chenketten hinzugefügt werden können: dtData-Table.ExtendedProperties.Add("Eingabe","Test- daten").

HasErrors Gibt einen Booleschen Wert zurück, der angibt, ob in einer der Datenzeilen der DataTable nach einer Aktion Fehler aufgetreten sind

Locale Setzt oder liest die Lokalisierungsinformation, die für Zei-chenkettenvergleiche in der DataTable ausgewertet wird

MinimumCapacity Setzt oder liest die Größe, die DataTable zu Beginn hatte

Namespace Setzt oder liest den Namensraum der XML-Repräsentation der Daten in dieser Tabelle

ParentRelations Gibt die Auflistung von übergeordneten Beziehungen für diese Tabelle zurück oder Nothing, wenn keine existiert

Prefix Setzt oder liest das Namensraum-Präfix der XML-Repräsen-tation der Daten in der DataTable

PrimaryKey Setzt oder liest ein Array von DataColumn-Objekten, das die Primärschlüssel für die DataTable darstellt

Name Beschreibung

Tabelle 5.16 DataTable-Eigenschaften (Forts.)

Page 35: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

348 ADO.NET und Datenbanken

DataTable-Methoden

Eine DataTable stellt die folgenden Methoden zur Verfügung:

Rows Gibt die Auflistung von DataRows zurück, die zu der Data-Table gehören, oder Nothing, wenn keine DataRow vor-handen ist

TableName Setzt oder liest den Namen der Tabelle. Der Name wird auch über die DataTableCollection des DataSets aus-gewertet.

Name Beschreibung

AcceptChanges() Übernimmt alle Änderungen, die an der DataTable seit dem letzten Aufruf dieser Methode oder seit dem Laden der DataTable vorgenommen wurden. Ändert den Zustand aller geänderten Zeilen auf unchanged und ist daher erst nach dem Aufruf der Update-Methode sinnvoll

BeginInit() Mit BeginInit kann gesteuert werden, wann eine Data-Table initialisiert wird, die auf einer Maske oder in einer Komponente verwendet werden soll. Nach Aufruf von BeginInit wird zur Laufzeit auf den Aufruf von EndInit gewartet, um sicherzustellen, dass die DataTable nicht verwendet wird, bevor sie vollständig initialisiert wurde.

BeginLoadData() Wird im Zusammenhang mit EndLoadData verwendet. Diese Methode deaktiviert Benachrichtigungen, Index-Aktualisierungen und Einschränkungen, während Daten geladen werden.

Clear() Löscht alle Daten aus der DataTable

Clone() Kopiert die Struktur der DataTable inklusive des Schemas der DataTable und ihrer Einschränkungen

Compute() Erwartet zwei Argumente als Zeichenketten. Wendet eine der beiden Aggregatfunktionen SUM oder COUNT, die als erstes Argument angegeben ist, auf die mit der im zweiten Argument angegebenen Bedingung gefilterten aktuellen Datenzeilen an.

Copy() Kopiert die Struktur und Daten der DataTable

Tabelle 5.17 DataTable-Methoden

Name Beschreibung

Tabelle 5.16 DataTable-Eigenschaften (Forts.)

Page 36: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 349

Ereignisse der DataTable

Datentabellen stellen Ereignisse zur Verfügung, mit denen Verände-rungen an Daten in Spalten und Zeilen gehandhabt werden können.Die DataTable kann sechs Ereignisse auslösen:

EndInit() Beendet die Initialisierung der DataTable in Verbindung mit BeginInit() zur Laufzeit und gibt sie zur Verwen-dung frei

EndLoadData() Wird im Zusammenhang mit BeginLoadData verwendet. Diese Methode aktiviert Benachrichtigungen, Index-Aktu-alisierungen und Einschränkungen, nachdem Daten gela-den wurden.

GetChanges() Gibt eine Kopie der DataTable zurück, die alle Datenzei-len enthält, die seit dem Laden der DataTable oder dem letzten Aufruf von AcceptChanges geändert worden sind.

GetErrors() Gibt ein Array von DataRows zurück, in denen ein Fehler aufgetreten ist

ImportRow() Kopiert eine DataRow in eine DataTable, wobei alle Eigen-schaften sowie der Originalinhalt und der aktuelle, mögli-cherweise geänderte Wert erhalten bleiben

LoadDataRow() Sucht und aktualisiert eine bestimmte Datenzeile. Wenn diese nicht gefunden werden kann, wird sie mit den ange-gebenen Werten erstellt.

NewRow() Erzeugt eine neue DataRow entsprechend dem Tabellen-schema

RejectChanges() Macht alle Änderungen, die seit dem Laden der Data-Table oder dem letzten Aufruf von AcceptChanges gemacht wurden, rückgängig

Reset() Versetzt die DataTable in ihren Originalzustand zurück

Select() Gibt ein Array von DataRows zurück, das nach dem Primärschlüssel, sofern vorhanden, sortiert ist

Name Beschreibung

Tabelle 5.17 DataTable-Methoden (Forts.)

Page 37: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

350 ADO.NET und Datenbanken

Die Ereignisse der DataTable sind paarweise angelegt, beispielsweisetritt RowChanging während der Änderung einer Datenzeile auf, Row-Changed, wenn sie erfolgreich geändert wurde.

GetErrors nachRowChanging

auswerten

Für eine Anwendung mit datengebundenen Eingabefeldern stellenDataTable-Ereignisse eine gute Möglichkeit dar, eingegebene Datenzu überprüfen. Problematische Datensätze können über die Get-Errors-Methode der DataTable entdeckt werden, nachdem dasRowChanging-Ereignis ausgelöst worden ist.

In der Fortsetzung des vorausgegangenen Beispiels sollen die Daten-zeilen der DataTable programmatisch geändert werden. In einer Pro-zedur DataTable_Füllen werden zunächst drei Tabellenzeilenerzeugt, die mit Hilfe der Prozedur DataTable_Ändern geändert wer-den, um das Änderungsereignis auszulösen.

Listing 5.30 Prozedur zum Füllen der Tabelle

Private Sub DataTable_Füllen() Dim i As Integer Dim drInhalt As DataRow For i = 1 To 3 drInhalt = dtKlimata.NewRow drInhalt("Klimaname") = "Name_" + i.ToString drInhalt("Temperatur") = Cint(Rnd(i) * 30)

dtKlimata.Rows.Add(drInhalt)

Ereignis Beschreibung

ColumnChanged Tritt ein, wenn ein Wert in eine Spalte erfolgreich einge-fügt werden konnte

ColumnChanging Tritt ein, wenn ein Wert in eine Spalte eingetragen wird

RowChanged Tritt ein, nachdem eine Datenzeile erfolgreich aktualisiert wurde

RowChanging Tritt ein, wenn eine Datenzeile in der Tabelle verändert wird

RowDeleted Tritt ein, wenn eine Datenzeile in der Tabelle als gelöscht markiert wurde

RowDeleting Tritt ein, bevor eine Datenzeile in der Tabelle als gelöscht markiert wird

Tabelle 5.18 DataTable-Ereignisse

Page 38: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 351

NextEnd Sub

Listing 5.31 Prozedur zum Ändern einer Datenzeile

Private Sub DataTable_Ändern() dtKlimata.Rows.Item(1)("Beschreibung") = 20End Sub

Ereignisprozeduren

Um ein Ereignis auszuwerten, muss zuerst eine entsprechende Ereig-nisprozedur angelegt werden.

Listing 5.32 Ereignisprozedur für die Spaltenänderung

Private Sub SpaltenÄnderung( _ ByVal sender As Object, _ ByVal e As DataColumnChangeEventArgs) MsgBox("In Datenzeile: " & _

e.Row("Klimaname").ToString & _ " soll die Spalte " & e.Column.ColumnName & _ " in: " + CStr(e.ProposedValue) & _ " geändert werden.")End Sub

Zum Aufruf der Ereignistests wird die Prozedur Main ergänzt unddarin das Füllen der Datenzeilen nach dem Einsetzen der Tabelle indas DataSet aufgerufen. Danach wird die Ereignisprozedur der Zei-lenänderung an den Ereignishandler der Tabelle gebunden und an-schließend die Änderung ausgelöst.

Listing 5.33 Auslösen des Änderungsereignisses, Auszug aus erweiterter Prozedur Sub Main()

' ... dsDataSet.Tables.Add(dtKlimata) ' Tabelle mit einigen Zeilen füllen DataTable_Füllen() ' Ereignisbehandlung an DataTable binden AddHandler dtKlimata.ColumnChanging, _ New DataColumnChangeEventHandler( _ AddressOf SpaltenÄnderung)

Page 39: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

352 ADO.NET und Datenbanken

' Tabelle ändern DataTable_Ändern() ' Fortsetzung Sub Main mit XML-Ausgabe dsDataSet.WriteXmlSchema("dtKlimataSchema.xml") dsDataSet.WriteXml("dtKlimata.xml")

' ...

Nach dem Start der Anwendung erscheint eine Meldung, die durchden Ereignishandler der Datentabelle ausgelöst wird.

Die Datei dtKlimata.xml im Projektausgabeverzeichnis \bin enthält diegeänderten Daten der Datentabelle dtKlimata.

Abbildung 5.31 Änderungsmeldung

Abbildung 5.32 Geänderte DataTable dtKlimata im DataSet

Page 40: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 353

Eigenschaften von Änderungsereignissen

Änderungsereignisse der DataTable haben die folgenden Eigenschaf-ten:

5.7.2 DataRow

Eine DataRow stellt eine einzelne Datenzeile in einer DataTable dar.Werden Daten eingefügt oder geändert, die dem Tabellenschemawidersprechen, wird in der Eigenschaft RowError eine Fehlermeldunggesetzt, die vor einer Aktualisierung der ursprünglichen Datenquelleausgewertet werden kann.

dtDataTable.NewRow

Eine DataRow wird über die NewRow-Methode einer Datentabelleerzeugt.

Listing 5.34 Erzeugung einer DataRow

Dim dtDataTable as DataTableDim drNeu as DataRowdrNeu = dtDataTable.NewRow()drNeu("pkTabelle") = 1drNeu("Testname") = "Neu"drNeu("Beschreibung" ) = "Testzeile"dtDatatable.Rows.Add(drNeu)

Eine neue Datenzeile wird immer mit dem Schema und den Spalten-informationen einer bestehenden DataTable angelegt. Sie kann auchzuerst mit Daten gefüllt werden, um anschließend zur Auflistung derDatenzeilen der DataTable hinzugefügt zu werden.

Eigenschaft Beschreibung

Column Gibt die Datenspalte zurück, deren Wert geändert wird

ProposedValue Setzt oder liest den neuen Wert, der in die Spalte eingetra-gen werden soll

Row Gibt die Datenzeile zurück, in der geändert wird

Tabelle 5.19 Eigenschaften des Änderungsereignisses einer DataTable

Page 41: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

354 ADO.NET und Datenbanken

DataRow-Eigenschaften

DataRow hat die folgenden Eigenschaften:

DataRow-Methoden

DataRow stellt die folgenden Methoden zur Verfügung:

Name Beschreibung

HasErrors Gibt einen Booleschen Wert zurück, der angibt, ob in der Datenzeile Fehler aufgetreten sind

Item Setzt oder liest Daten in einer angegebenen Spalte

ItemArray Gibt alle Werte dieser Zeile in einem Array zurück bzw. setzt alle Werte dieser Zeile aus einem Array

RowError Setzt oder liest eine Fehlerbeschreibung für eine Zeile

RowState Gibt den aktuellen Zustand der Datenzeile zurück und wird zur Auswertung von Datenänderungen genutzt

Table Gibt die DataTable zurück, zu der diese DataRow gehört

Tabelle 5.20 DataRow-Eigenschaften

Name Beschreibung

AcceptChanges() Übernimmt alle Änderungen, die an der DataRow seit dem letzten Aufruf dieser Methode oder seit dem Laden der DataRow vorgenommen wurden

BeginEdit() Startet eine Änderungsaktion an der Datenzeile, wäh-rend der alle Ereignisse deaktiviert sind. Diese Methode wird zusammen mit EndEdit() und CancelEdit() ver-wendet.

CancelEdit() Bricht die mit BeginEdit() eingeleitete Änderung der Datenzeile ab

ClearErrors() Mit dieser Methode werden alle Fehler gelöscht, die aus Zeilenfehlern oder aus der Methode SetColumnError() stammen

Delete() Löscht die Datenzeile

EndEdit() Beendet die Änderungen an der Datenzeile

Tabelle 5.21 DataRow-Methoden

Page 42: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 355

Die Verwendung der GetChildRows- und GetParentRows-Metho-den wird in Abschnitt 5.8.1, »DataRelation«, beschrieben.

Werte der DataRowVersion

Die mit der HasVersion-Methode der DataRow ausgewertete Eigen-schaft DataRowVersion kann folgende Werte annehmen:

GetChildRows() Gibt die Detaildaten einer Datenzeile zurück. Diese Methode wird mit einer DataRelation und der Data-RowVersion aufgerufen.

GetColumnError() Gibt die Fehlerbeschreibung einer Datenspalte zurück. Wird mit einem DataColumn-Objekt, einer Ordinalzahl oder dem Spaltennamen als Argument aufgerufen

GetColumnsInEr-ror()

Gibt ein Array der Spalten zurück, in denen Fehler aufge-treten sind

GetParentRow() Gibt die der aktuellen Datenzeile übergeordnete Daten-zeile zurück. Diese Methode wird mit einer DataRela-tion und der DataRowVersion aufgerufen.

GetParentRows() Gibt ein Array der übergeordneten Datenzeilen zurück. Diese Methode wird mit einer DataRelation und der DataRowVersion aufgerufen.

HasVersion() Gibt einen Booleschen Wert zurück, der angibt, ob eine bestimmte Version der Datenzeile existiert. Wird mit einem der DataRowVersion-Werte Current, Default, Original oder Proposed als Argument aufgerufen.

IsNull() Gibt einen Booleschen Wert zurück, der angibt, ob die als Argument angegebene Spalte einen NULL-Wert ent-hält

RejectChanges() Verwirft alle Änderungen, die an der Datenzeile gemacht wurden, seit das letzte Mal AcceptChanges aufgerufen wurde oder die Datenzeile geladen wurde

SetColumnError() Setzt die Fehlerbeschreibung für die als Argument ange-gebene Datenspalte

SetParentRow() Setzt die der aktuellen Datenzeile übergeordnete Daten-zeile. Diese Methode wird mit einer Datenzeile oder einer DataRelation und einer Datenzeile aufgerufen.

Name Beschreibung

Tabelle 5.21 DataRow-Methoden (Forts.)

Page 43: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

356 ADO.NET und Datenbanken

5.7.3 DataView

Eine DataView ist eine optional gefilterte Sicht auf die Daten in einemDataSet. Es können mehrere DataViews für ein DataSet erstellt wer-den, um damit Daten zu filtern, zu sortieren oder zu suchen. Steuer-elemente können direkt an DataViews gebunden werden. Für eineDataView können Eigenschaften festgelegt werden, die von jenen derDatentabelle abweichen, d.h., Sie können Daten filtern, sortieren undvor dem Editieren oder Löschen schützen, ohne die zugrunde lie-gende DataTable zu verändern.

BeispieldvDropDown

In einem einfachen Beispiel soll ein Dropdown mit den Gewürzna-men aus einer DataView gefüllt werden. Der Inhalt des Dropdownssoll sortiert und gefiltert werden. Sie finden das fertige Projekt auf derbeiliegenden CD-ROM unter \Kapitel05\dvDropDown.

Legen Sie eine neue Windows-Anwendung an, blenden Sie in derEntwurfsansicht von Form1 die Toolbox ein und platzieren Sie ausdem Abschnitt Windows Forms eine Combobox auf der Maske, die Sieim Eigenschaftenfenster DropDown benennen.

Auf der Maske sollen außer dem Gewürznamen im Dropdown auchdie anderen Daten des ausgewählten Gewürzes angezeigt werden.Ziehen Sie dazu ein Label auf die Form1, das Sie lblSelectedID nen-nen, und fügen Sie drei Textboxen mit den Namen txtName, txtGat-tung und txtBeschreibung hinzu.

Eigenschaft Beschreibung

Current Aktueller Wert der Datenzeile

Default Zustand der Datenzeile, wenn für neu erstellte Daten-zeilen Vorgabewerte definiert sind und angewendet wurden

Original Als unverändert behandelte Version der Datenzeile, die nach der Erstellung oder dem Aufruf von AcceptChanges vorliegt

Proposed Wert nach der Änderung von Werten, bevor AcceptChanges aufgerufen wurde

Tabelle 5.22 Mögliche Werte der DataRowVersion

Page 44: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 357

Fügen Sie in der Code-Ansicht von Form1 Verweise auf die Namens-räume ConfigurationSettings, OleDB und SqlClient hinzu:

Imports System.Configuration.ConfigurationSettingsImports System.Data.OleDbImports System.Data.SqlClient

Deklarieren Sie ein DataSet, eine DataTable und eine DataView.

Dim dsDropDown As DataSetDim dtDropDown As DataTableDim dvDropDown As DataView

In der Prozedur DropDown_Füllen soll ein DataSet über einenDatenadapter mit einer einzigen Tabelle gefüllt werden. Der Beispiel-code verwendet Datenprovider-unabhängigen Code, das Beispielfunktioniert daher sowohl mit einer Access-Datenbank im Anwen-dungsverzeichnis \bin als auch mit der Datenbank dbWürzen auf demSQL Server. Die Information über den zu wählenden Datenproviderwird zur Laufzeit der Konfigurationsdatei <Anwendungsname>.exe.config entnommen.

Listing 5.35 Code zum Füllen des Dropdowns aus einer DataView

Private Sub DropDown_Füllen() Dim _str As String _str = "SELECT pkGewürz,Gewürzname, " & _ " Gattung,Beschreibung " & _ " FROM tblGewürze" ' Allgemeiner Datenbankzugriff Dim _conn As IDbConnection Dim _cmd As IDbCommand Dim _da As IDbDataAdapter ' Verbindungsauswahl auswerten Select Case AppSettings("Verbindungstyp").ToUpper Case "SQL"

_conn = New SqlConnection( _ AppSettings("conSQL")) _cmd = New SqlCommand(_str) _cmd.Connection = _conn _da = New SqlDataAdapter(_cmd) Case "OLEDB"

_conn = New OleDbConnection( _ AppSettings("conOleDB"))

Page 45: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

358 ADO.NET und Datenbanken

_cmd = New OleDbCommand(_str) _cmd.Connection = _conn _da = New OleDbDataAdapter(_cmd) End Select ' DataSet über den DataAdapter füllen lassen dsDropDown = New DataSet() _da.Fill(dsDropDown) ' DataView für DataSet erstellen dtDropDown = dsDropDown.Tables(0) dvDropDown = dsDropDown.DefaultViewManager. _ CreateDataView(dtDropDown) ' DropDown an DataView binden DropDown.DataSource = dvDropDown DropDown.ValueMember = "pkGewürz" DropDown.DisplayMember = "Gewürzname"End Sub

Die DataView wird mit Hilfe des DefaultViewManagers des DataSetserstellt, dessen CreateDataView-Methode auf die einzige Tabelleangewendet wird.

Datenbindung Das Dropdown wird über seine Eigenschaften DataSource, DataMem-ber und ValueMember an die DataView gebunden. Die Textfeldinhaltewerden direkt an Tabellenspalten gebunden.

Listing 5.36 Datenbindung der Formularfelder

Private Sub Datenbindung_Formularfelder() ' Steuerelemente an DataView binden Try

lblSelectedID.DataBindings.Add("Text", _ dvDropDown, "pkGewürz") txtBeschreibung.DataBindings.Add("Text", _ dvDropDown, "Beschreibung") txtGattung.DataBindings.Add("Text", _ dvDropDown, "Gattung") txtGewürzname.DataBindings.Add("Text", _ dvDropDown, "Gewürzname") Catch ex As Exception MessageBox.Show(ex.Message) End TryEnd Sub

Page 46: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 359

Der Code zum Füllen des Dropdowns sowie die Datenbindungenwerden beim Laden der Maske aus der Ereignisprozedur Form1_Loadaufgerufen.

Listing 5.37 Aktionen beim Laden der Maske

Private Sub Form1_Load( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load

DropDown.Items.Clear() DropDown_Füllen() Datenbindung_Formularfelder()End Sub

Wenn Sie das Projekt ausführen, sehen Sie als Ergebnis eine Daten-maske mit gefülltem Dropdown (siehe Abbildung 5.33).

Filtern und Sortieren

Daten filtern und sortieren mit DataView

Um die Sortierungs- und Filtermöglichkeiten der DataView zu testen,fügen Sie der Maske eine Schaltfläche mit dem Namen btnFilternund eine Textbox mit dem Namen txtFilter hinzu.

Klicken Sie doppelt auf btnFiltern, um den Code für die Filterbedin-gung anzugeben.

Abbildung 5.33 Datenmaske mit Dropdown aus DataView

Page 47: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

360 ADO.NET und Datenbanken

Listing 5.38 Setzen der Filterbedingungen für die DataView

Private Sub btnFiltern_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnFiltern.Click Try ' Filterbedingungen setzen

dvDropDown.Sort = "Gewürzname DESC" dvDropDown.RowFilter = txtFilter.Text Catch ex As Exception MessageBox.Show(ex.Message) End TryEnd Sub

Bevor RowFilter verwendet werden kann, muss die Eigenschaft Sorteine Sortierbedingung erhalten. Die Eigenschaft RowFilter entnimmtdie Filterbedingung der Textbox txtFilter.

Starten Sie die Anwendung und geben Sie in die neue Textbox als Fil-terbedingung "Gewürzname like 'K%' and id < 1023" ein. ÖffnenSie das Dropdown, um die gefilterten Datensätze zu sehen.

Where undOrder by

Beide genannten Eigenschaften akzeptieren Fragmente von SQL-Anweisungen, dabei funktioniert RowFilter ähnlich wie ein WHERE-Filter in SQL, Sort ähnlich wie eine ORDER BY-Klausel.

Abbildung 5.34 Sortierte und gefilterte Daten im Dropdown

Page 48: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenobjekte des DataSets 361

Daten suchen

Fügen Sie der Maske eine Schaltfläche mit dem Namen btnSuchenund eine Textbox mit dem Namen txtSuche hinzu.

Methode Find()Um einzelne Datensätze gezielt zu suchen, wird zur Sicherheit zuerstder Filter deaktiviert. Die Suche besteht im Auswerten der MethodeFind, die entweder die Zeilenposition der gesuchten Zeile oder, wennnichts gefunden wurde, -1 als Wert zurückgibt.

Listing 5.39 Suchfunktion

Private Sub btnSuchen_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnSuchen.Click ' Filter für Suche zurücksetzen txtFilter.Text = "" dvDropDown.RowFilter = "" dvDropDown.Sort = "Gewürzname ASC" ' Datensatznummer suchen Dim _int As Integer

_int = dvDropDown.Find(txtSuche.Text) ' Zum gefundenen Datensatz navigieren

Me.BindingContext.Item(dvDropDown).Position = _intEnd Sub

Abbildung 5.35 Suche in der Datenmaske

Page 49: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

362 ADO.NET und Datenbanken

Mit der Position der gefundenen Zeile kann über die Datenbindungder Maske der Datensatz in allen gebundenen Steuerelementen ange-zeigt werden. Gibt es als Ergebnis einer Suche mehrere Datenzeilen,speichert die Methode FindRows alle Fundstellen als Array.

DataView-Eigenschaften

Die Eigenschaften einer DataView sind:

Name Eigenschaften

AllowDelete Setzt oder liest den Wert, der festlegt, ob das Löschen von Daten zugelassen ist

AllowEdit Setzt oder liest den Wert, der festlegt, ob das Ändern von Daten zugelassen ist

AllowNew Setzt oder liest den Wert, der festlegt, ob Daten über die Methode AddNew hinzugefügt werden dürfen

ApplyDefaultSort Setzt oder liest den Wert, der festlegt, ob nach der Standardvorgabe sortiert werden soll

Count Liest die Anzahl der Datensätze aus, nachdem RowFil-ter und RowStateFilter angewendet worden sind

DataViewManager Gibt den DataViewManager zurück, der mit dieser DataView verbunden ist

Item Identifiziert eine Datenzeile in der Datentabelle in der Form dvDataView.Item(4)

RowFilter Setzt oder liest die Zeichenkette, die eine Anweisung enthält, mit der die Datenzeilen für die Sichtbarkeit in der DataView gefiltert werden sollen

Sort Setzt oder liest die Spalten, nach denen sortiert werden soll, und legt die Sortierrichtung fest. Enthält die Spal-tennamen und die Sortierrichtung ähnlich der SQL-Klausel ORDER BY

Table Setzt oder liest die DataTable, aus der die DataView mit Daten versorgt wird. Diese Eigenschaft kann nur von Nothing auf einen Wert gesetzt werden.

Tabelle 5.23 DataView-Eigenschaften

Page 50: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Tabellenverknüpfungen 363

DataView-Methoden

Eine DataView stellt folgende Methoden zur Verfügung:

5.8 Tabellenverknüpfungen

Verknüpfte Tabellen

Das Laden mehrerer Tabellen in ein DataSet überträgt keine in derDatenbank definierten Tabellenverknüpfungen. Unter Umständenfehlen deshalb im DataSet notwendige Beziehungen, mit denen inder Datenbank die Datenintegrität überwacht wird. Sie können dieseBeziehungen im DataSet über DataRelation-Objekte entsprechendnachbilden oder auch bewusst abweichend definieren.

5.8.1 DataRelation

DataRelation-Objekte sind Teil des DataSets und werden zur Her-stellung von Tabellenbeziehungen durch die Verknüpfung von über-und untergeordneten Datenspalten desselben Datentyps verwendet.Diese Beziehungen legen Regeln und Abhängigkeiten für die Datenin-

Name Beschreibung

AddNew() Fügt der DataView eine neue Datenzeile vom Typ DataRowView hinzu

BeginInit() Mit BeginInit kann gesteuert werden, wann eine DataView initialisiert wird, die auf einer Maske oder in einer Komponente verwendet werden soll. Nach Aufruf von BeginInit wird zur Laufzeit auf den Aufruf von EndInit gewartet, um sicherzustel-len, dass die DataView nicht verwendet wird, bevor sie vollstän-dig initialisiert wurde.

Delete() Löscht eine Datenzeile an der angegebenen Zeilenposition in der Form dvDataView.Delete(4)

EndInit() Gibt das Ende der Initialisierung der DataView in Verbindung mit BeginInit() zur Laufzeit an und gibt sie zur Verwendung frei

Find() Gibt die Zeilenposition einer zu suchenden Datenzeile zurück, die über einen oder mehrere in Sort definierte Schlüsselwerte identifiziert wird

FindRows() Gibt die Zeilenposition mehrerer zu suchender Datenzeilen als Array zurück, die über einen oder mehrere in Sort definierte Schlüsselwerte identifiziert werden

Tabelle 5.24 DataView-Methoden

Page 51: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

364 ADO.NET und Datenbanken

tegrität in den beteiligten Datentabellen fest und werden bei allenAktionen im DataSet überwacht.

Mit Hilfe von DataRelation-Objekten ist es auch möglich, hierarchi-sche Datenmengen programmatisch zu erzeugen.

DataRelation anlegen

Eine DataRelation wird zwischen einer oder mehreren Spalten ineiner Hauptdatentabelle und einer gleichen Anzahl von Spalten ineiner Detaildatentabelle erzeugt.

BeispielrlDataGrid

Im folgenden Beispiel wird eine Beziehung zwischen zwei Daten-tabellen im Programmcode erzeugt. Der Vorgang entspricht inhaltlichdem in Abbildung 5.24 dargestellten Einrichten einer Tabellenbe-ziehung aus der Schemadarstellung eines DataSets. Sie finden das fer-tige Beispiel rlDataGrid auf der beiliegenden CD-ROM im Verzeichnis\Kapitel05\rlDataGrid.

Legen Sie eine neue Windows-Anwendung an und ziehen Sie in derEntwurfsansicht ein DataGrid aus der Toolbox auf die Maske Form1.Fügen Sie im Projektmappen-Explorer die Datei App.config hinzu, inder Sie wie gehabt die Verbindungszeichenketten verschiedenerDatenbanken speichern können. Der im Folgenden gezeigte Beispiel-code funktioniert gleichermaßen mit der SQL Server- und der Access-Variante der Datenbank dbWürzen.

Fügen Sie in der Code-Ansicht von Form1 Verweise auf die Namens-räume ConfigurationSettings, OleDb und SqlClient hinzu:

Imports System.Configuration.ConfigurationSettingsImports System.Data.OleDbImports System.Data.SqlClient

Deklarieren Sie ein DataSet ds, das die zu verknüpfenden Tabellenaufnehmen soll:

Private ds As New DataSet()

Das Laden der Daten findet in der Prozedur TabellenLaden statt, dieaus der Ereignisprozedur Form1_Load aufgerufen wird.

Page 52: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Tabellenverknüpfungen 365

Listing 5.40 Laden der Tabellen

Private Sub TabellenLaden() ' SQL Anweisungen Dim _str1 As String = "SELECT * " & _ " FROM tblKlimata " Dim _str2 As String = "SELECT * " & _ " FROM tblRegionen" ' Allgemeiner Datenbankzugriff Dim _conn As IDbConnection Dim _cmd1 As IDbCommand Dim _cmd2 As IDbCommand ' Verbindungsauswahl auswerten Select Case AppSettings("Verbindungstyp").ToUpper Case "SQL" _conn = New SqlConnection( _ AppSettings("conSQL")) _cmd1 = New SqlCommand(_str1) _cmd1.Connection = _conn _cmd2 = New SqlCommand(_str2) _cmd2.Connection = _conn ' DataSet über DataAdapter füllen Dim _da1 As SqlDataAdapter _da1 = New SqlDataAdapter(_cmd1) _da1.Fill(ds, "Klimata") Dim _da2 As SqlDataAdapter _da2 = New SqlDataAdapter(_cmd2) _da2.Fill(ds, "Regionen") Case "OLEDB" _conn = New OleDbConnection( _ AppSettings("conOleDB")) _cmd1 = New OleDbCommand(_str1) _cmd1.Connection = _conn _cmd2 = New OleDbCommand(_str2) _cmd2.Connection = _conn ' DataSet über DataAdapter füllen Dim _da1 As OleDbDataAdapter _da1 = New OleDbDataAdapter(_cmd1) _da1.Fill(ds, "Klimata") Dim _da2 As OleDbDataAdapter _da2 = New OleDbDataAdapter(_cmd2)

Page 53: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

366 ADO.NET und Datenbanken

_da2.Fill(ds, "Regionen") End SelectEnd Sub

Die Daten werden in die Tabellen Klimata und Regionen des DataSetsgeladen, für die in der Prozedur TabellenVerknüpfen eine Beziehungdefiniert wird.

Listing 5.41 Erzeugen einer DataRelation

Private Sub TabellenVerknüpfen() ' Tabellenbeziehung hinzufügen ds.Relations.Add( _ New DataRelation( _ "relKlimataRegionen", _ ds.Tables("Klimata").Columns("pkKlima"), _ ds.Tables("Regionen").Columns("fkKlima")))End Sub

Ähnlich wie bei einer JOIN-Anweisung in SQL wird die Zuordnungüber die Tabellennamen und die zu verknüpfenden Spalten angege-ben. Im Gegensatz zur JOIN-Anweisung ist eine DataRelation auchaußerhalb von SQL-Anweisungen wirksam. Die Syntax lautet:

New DataRelation(RelationName, ParentColumn, ChildColumn)

Sollen mehrere Spalten gleichzeitig verknüpft werden, kann anstelleeiner einzelnen DataColumn auch ein Array von Datenspalten angege-ben werden.

Die neu erstellte Tabellenbeziehung wird erst mit der Einfügung in dieAuflistung der DataRelations des DataSets wirksam.

DataRelation-Eigenschaften

Ein DataRelation-Objekt hat folgende Eigenschaften:

Name Beschreibung

ChildColumns Ruft die untergeordneten DataColumn-Objekte dieser Beziehung ab

ChildKeyConstraint Ruft die ForeignKeyConstraint für die Beziehung ab

Tabelle 5.25 DataRelation-Eigenschaften

Page 54: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Tabellenverknüpfungen 367

5.8.2 Darstellung verknüpfter Tabellen

Zur Anzeige der verknüpften Tabellen in einem DataGrid genügt es,dessen DataSource-Eigenschaft an die Tabelle mit den Hauptdaten zubinden.

Listing 5.42 Anzeigen der verknüpften Daten

Private Sub TabellenAnzeigen() ' Verknüpfte Tabellen in einem DataGrid anzeigen DataGrid1.DataSource = ds.Tables("Klimata")End Sub

Ergänzen Sie in Form1_Load den Aufruf der Prozeduren TabellenVer-knüpfen und TabellenAnzeige und starten Sie dann die AnwendungrlDataGrid.

Listing 5.43 Aufruf der Verknüpfung und Anzeige

Private Sub Form1_Load( _ ByVal sender As Object, _

ChildTable Ruft die untergeordnete Tabelle dieser Beziehung ab

DataSet Ruft das DataSet ab, zudem die DataRelation gehört

ExtendedProperties Ruft die Auflistung ab, in der angepasste Eigenschaf-ten gespeichert werden

Nested Ruft einen Wert ab, der angibt, ob DataRelation-Objekte geschachtelt sind, oder legt diesen fest

ParentColumns Ruft ein Array von DataColumn-Objekten ab, die die übergeordneten Spalten dieser DataRelation sind

ParentKeyConstraint Ruft die UniqueConstraint ab, durch die sicherge-stellt wird, dass Werte in der übergeordneten Spalte einer DataRelation eindeutig sind

ParentTable Ruft die übergeordnete DataTable dieser DataRela-tion ab

RelationName Ruft den Namen ab, der zum Abrufen einer DataRe-lation aus der DataRelationCollection verwen-det wird, oder legt diesen fest

Name Beschreibung

Tabelle 5.25 DataRelation-Eigenschaften (Forts.)

Page 55: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

368 ADO.NET und Datenbanken

ByVal e As System.EventArgs) _ Handles MyBase.Load Call TabellenLaden() Call TabellenVerknüpfen() Call TabellenAnzeigen()End Sub

Im DataGrid wird zusätzlich zum Inhalt der Hauptdatentabelle Kli-mata unter jedem Knoten im Zeilenkopf ein Link eingeblendet, derden Namen der DataRelation relKlimataRegionen trägt. Wenn Siediesem Link folgen, wird im DataGrid danach die DetaildatentabelleRegionen angezeigt (siehe Abbildung 5.37). Dieser Vorgang geschiehtselbsttätig durch Interaktion des DataGrids mit den Methoden derDataRelation, d.h. ohne einen Wechsel der Datenbindung.

Navigation imDataGrid

In der Kopfzeile des DataGrids werden in der Detaildatenanzeige derTabellenname und der Inhalt des Hauptdatensatzes angezeigt. Überdie Symbole auf der rechten Seite kann zur Hauptdatentabelle zurücknavigiert oder die Hauptdatensatzinformation ausgeblendet werden.Die Detaildatentabelle könnte im Prinzip Links auf weitere Unter-tabellen enthalten, die auf die gleiche Art zu erreichen wären.

Abbildung 5.36 Anzeige verknüpfter Tabellen im DataGrid

Abbildung 5.37 Anzeige einer verknüpften Detaildatentabelle im DataGrid

Page 56: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Tabellenverknüpfungen 369

In diesem Beispiel wird nur eine einfache Relation zwischen zweiTabellen dargestellt. Ein komplexeres Anwendungsbeispiel von Relati-onen mehrerer hierarchisch verknüpfter Tabellen finden Sie imAbschnitt 5.11.1, »Datengebundenes Treeview«.

5.8.3 Zugriff auf Detaildaten

Der Zugriff auf die Detaildaten in einer verknüpften Tabelle lässt sichauch programmatisch einrichten. Die Detaildaten einer DataRelationsind über die GetChildRows-Methode einer einzelnen DataRow in derHauptdatentabelle zugänglich und werden dabei in ein Array vonDatenzeilen übertragen. Der Aufruf folgt der Syntax:

RowArray() = ds.Tables(TabellenName).Rows(Index). _ GetChildRows(RelationName)

GetChildRows testen

Erweitern Sie die Anwendung um eine Prozedur zum Test der Get-ChildRows-Methode, die beim Klick auf einen Datensatz in derHauptdatentabelle ausgelöst wird. Wählen Sie dazu aus dem linkenCodenavigations-Dropdown DataGrid1, dann aus dem rechtenMouseDown, um die beim Klick auf das DataGrid1 auszulösende Ereig-nisprozedur anzulegen.

HitTestDer Klick auf das DataGrid lässt sich über dessen HitTest-Methodeauswerten, die die Koordinaten einer angeklickten Tabellenzellezurückgibt. Für die DataRow in der dazugehörigen Tabellenzeile wirdim Beispiel mit GetChildRows die Anzahl der vorhandenen Detailda-tensätze ausgelesen und im Ausgabefenster angezeigt. Starten Sie dieAnwendung im Debugmodus, um die Ausgabe der Testprozedur zusehen.

Listing 5.44 Zugriff auf die Detaildaten einer verknüpften Tabelle

Private Sub DataGrid1_MouseDown( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles DataGrid1.MouseDown ' Koordinaten des Klicks auf das DataGrid auswerten Dim htHitTest As _ System.Windows.Forms.DataGrid.HitTestInfo

Page 57: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

370 ADO.NET und Datenbanken

htHitTest = DataGrid1.HitTest(e.X, e.Y) If htHitTest.Row >= 0 Then ' Datenzeile im DataGrid ermitteln Dim _intRow As Integer _intRow = DataGrid1.Item(htHitTest.Row - 1, 0) ' Detaildaten der Relation in Array laden Dim arrRow() As DataRow arrRow = ds.Tables("Klimata").Rows(_intRow). _ GetChildRows("relKlimataRegionen") Console.WriteLine() Console.Write(" Es sind diesem Klima " & _ arrRow.Length & " Regionen zugeordnet") End IfEnd Sub

GetParentRows

In gleicher Weise erhalten Sie Zugriff auf den Hauptdatensatz einesDetaildatensatzes, indem Sie die GetParentRows-Methode einerDataRow aus der Detaildatentabelle anwenden. In diesem Fall ist dasErgebnis kein Array, sondern ein einzelner Datensatz.

5.9 Datenauswahl und Datenaktualisierung

Wie im Abschnitt 5.5, »Datenadapter für das DataSet«, dargestelltwurde, verwenden Datenadapter zum Aktualisieren, Löschen undEinfügen von Datensätzen in der Datenbank verschiedene Command-Objekte mit eigenen SQL-Anweisungen. Bei der Verwendung einesAssistenten zur Konfiguration eines Datenadapters, wie es inAbschnitt 5.5.2, »Datenadapter mit Assistenten konfigurieren«,beschrieben ist, werden für eine gegebene SQL-Anweisung zurDatenauswahl automatisch die entsprechenden SQL-Anweisungenoder Gespeicherten Prozeduren zur Aktualisierung der Datenbankerstellt.

AutomatischeAktualisierung

Das Objekt, das diese Aufgabe übernimmt, ist der CommandBuilder,der auch außerhalb des Datenadapter-Assistenten eingesetzt werdenkann. Gegenüber manuell angelegten Command-Objekten zur Aktuali-sierung der Datenbank hat die Verwendung eines CommandBuilder-Objektes den Vorteil, dass nach einer Änderung der SQL-Anweisung

Page 58: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenauswahl und Datenaktualisierung 371

für die Datenauswahl die SQL-Anweisungen zur Datenaktualisierungautomatisch erneuert werden.

5.9.1 CommandBuilder

Die Verwendung des CommandBuilders im Programmcode ist denk-bar einfach: Für ein manuell erstelltes DataAdapter-Objekt, das miteinem gültigen Command-Objekt zum Füllen eines DataSets verwen-det wird, genügt die bloße Erzeugung eines CommandBuilder-Objek-tes, um die Aktualisierung der Datenquelle zu ermöglichen.

Listing 5.45 CommandBuilder für Datenadapter erzeugen

' Pseudocode zur Verdeutlichung des Verfahrens_cmd = New SqlCommand(SELECT-Anweisung)' DataAdapter initialisieren_da = New SqlDataAdapter(_cmd)_da.Fill(ds)' Datenmanipulation in der Anwendung' ...Try ' INSERT-, DELETE- und UPDATE-Anweisungen ' vom CommandBuilder erstellen lassen Dim _cb As New SqlCommandBuilder(_da) _da.Update(ds)Catch ex As Exception ' ...End Try

Ein CommandBuilder-Objekt wird für einen einzelnen DataAdapterangelegt und stellt die automatisch erzeugten SQL-Anweisungen überseine Methoden GetInsertCommand, GetDeleteCommand und GetUp-dateCommand zur Verfügung. Diese Methoden können zum Auslesender SQL-Anweisungen genutzt werden, um diese manuell zu verän-dern oder zu ergänzen.

Listing 5.46 CommandBuilder-Anweisungen auslesen

' Pseudocode zur Verdeutlichung des Verfahrens_cmd = New SqlCommand(SELECT-Anweisung)' DataAdapter initialisieren_da = New SqlDataAdapter(_cmd)_da.Fill(ds)

Page 59: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

372 ADO.NET und Datenbanken

' Datenmanipulation in der Anwendung' ...Try Dim _cb As New SqlCommandBuilder(_da) ' INSERT-, DELETE- und UPDATE-Anweisungen ' des CommandBuilders auslesen ' und ggf. nachbearbeiten

_da.InsertCommand = _cb.GetInsertCommand_da.DeleteCommand = _cb.GetDeleteCommand_da.UpdateCommand = _cb.GetUpdateCommand

_da.Update(ds)Catch ex As Exception ' ...End Try

Der CommandBuilder versagt bei der Verwendung von unzulässigenTabellen- und Spaltennamen, die vordefinierten Begriffen entspre-chen (siehe Abschnitt 4.2.3, »Benennungsregeln«). Es ist möglich, mitHilfe der Eigenschaften QuotePrefix und QuoteSuffix diese Namenähnlich wie in Access in die Klammerzeichen [ ] einzubetten, umdamit einige Probleme des CommandBuilders zu vermeiden. Die bes-sere Methode ist aber immer noch die konsequente Vermeidung vor-definierter Begriffe.

CommandBuilder-Eigenschaften

Ein CommandBuilder-Objekt hat folgende Eigenschaften:

Name Beschreibung

DataAdapter Ruft ein DataAdapter-Objekt ab, für das automatisch SQL-Anweisungen oder Transact-SQL-Anweisungen generiert wer-den, oder legt dieses fest

QuotePrefix Ruft das oder die Anfangszeichen ab, die beim Angeben von Namen für SQL Server-Objekte (z.B. Tabellen oder Spalten) verwendet werden sollen, die Zeichen wie Leerzeichen enthalten, oder legt diese fest

QuoteSuffix Ruft das oder die Endzeichen ab, die beim Angeben von Namen für SQL Server-Objekte (z.B. Tabellen oder Spalten) verwendet werden sollen, die Zeichen wie Leerzeichen enthalten, oder legt diese fest

Tabelle 5.26 Eigenschaften des CommandBuilder-Objektes

Page 60: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenauswahl und Datenaktualisierung 373

CommandBuilder-Methoden

Ein CommandBuilder-Objekt stellt folgende Methoden zur Verfügung:

5.9.2 Aktualisieren von Autowerten

Bei Verwendung des CommandBuilders in einer Anwendung, die eserlaubt, im DataSet neue Datensätze anzulegen, ist es notwendig, dasAktualisieren von Datentabellen mit automatischer Schlüsselwertver-gabe genauer zu planen:

� Im DataSet und in der Datenbank müssen unterschiedliche Auto-werte für neue Datensätze vergeben werden, die sich nicht über-schneiden sollten. Am einfachsten ist dies über die Definition vonnegativen Autowerten für Schlüsselfelder im DataSet zu erreichen(siehe auch das Beispiel in Abschnitt 7.2.4, »Webdienst zur Aktuali-sierung der Datenbank«).

� Beim Einfügen der neuen Datensätze sollten in der Datenbank neuvergebene Autowerte auch in das DataSet der Anwendung über-

Name Beschreibung

DeriveParameters Füllt die Parameter-Auflistung des angegebenen Command-Objekts mit den Parameterinformationen für eine in Command angegebene Gespeicherte Prozedur auf

GetDeleteCommand Ruft das für Löschvorgänge in der Datenbank erforder-liche, automatisch generierte Command-Objekt ab, wenn eine Anwendung Update für DataAdapter aufruft

GetInsertCommand Ruft das für Einfügevorgänge in der Datenbank erfor-derliche, automatisch generierte Command-Objekt ab, wenn eine Anwendung Update für DataAdapter auf-ruft

GetUpdateCommand Ruft das für Aktualisierungen in der Datenbank erfor-derliche, automatisch generierte Command-Objekt ab, wenn eine Anwendung Update für DataAdapter auf-ruft

RefreshSchema Aktualisiert die Schemainformationen der Datenbank, die zum Generieren von INSERT-Anweisungen, UPDATE-Anweisungen und DELETE-Anweisungen verwendet werden

Tabelle 5.27 Methoden des CommandBuilder-Objektes

Page 61: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

374 ADO.NET und Datenbanken

tragen werden, um dort mit den aktualisierten Schlüsselwertenweiter zu arbeiten.

@@identity undscope_identity()

Der zuletzt von der Datenbank erzeugte Schlüsselwert kann mitHilfe der Systemvariablen des SQL Servers @@IDENTITY, die auch inAccess 2000 zur Verfügung steht, ausgelesen werden. Der SQL Ser-ver 2000 bietet alternativ den funktionsgleichen Aufruf scope_identity, der sicherstellt, dass der erzeugte Schlüsselwert tatsäch-lich aus der Einfügeaktion innerhalb der eigenen Transaktion ent-standen ist.

Für die erfolgreiche Aktualisierung des DataSets mit automatischerzeugten Schlüsselwerten sind zwei Voraussetzungen erforderlich:

� Die INSERT-Anweisung muss mit einer zweiten Anweisung, die@@IDENTITY oder scope_identity abfragt, ergänzt werden.

� Die UpdatedRowSource-Eigenschaft des InsertCommand-Objektesmuss auf FirstReturnedRecord gesetzt werden, damit die entspre-chende Datenzeile des DataSets mit dem neuen Datenschlüsselaktualisiert wird.

Listing 5.47 Vorbereitung zur Aktualisierung von Autowerten

' Pseudocode zur Verdeutlichung des Verfahrens_cmd = New SqlCommand(SELECT-Anweisung)' DataAdapter initialisieren_da = New SqlDataAdapter(_cmd)_da.Fill(ds)' Datenmanipulation in der Anwendung' ...Try Dim _cb As New SqlCommandBuilder(_da) ' INSERT-, DELETE- und UPDATE-Anweisungen ' des CommandBuilders auslesen ' und ggf. nachbearbeiten

_da.InsertCommand = _cb.GetInsertCommand _da.InsertCommand.CommandText = _da.InsertCommand.CommandText & "; " & _ "SELECT * FROM Tabelle " & _ "WHERE pkTabelle = @@IDENTITY" _da.InsertCommand.UpdatedRowSource = _ UpdateRowSource.FirstReturnedRecord

Page 62: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenbindung und Datennavigation 375

_da.DeleteCommand = _cb.GetDeleteCommand _da.UpdateCommand = _cb.GetUpdateCommand _da.Update(ds)Catch ex As Exception ' ...End Try

Die Aktualisierung von Autowerten im DataSet wird für SqlData-Adapter, die Sie mit dem Visual Studio .NET-Assistenten erstellen, inder beschriebenen Weise automatisch eingerichtet. Dies gilt nicht fürOleDbDataAdapter, da nicht alle OleDB-Datenquellen eine Variable@@IDENTITY unterstützen. Wenn Sie Access 2000-Datenbanken ver-wenden oder über den OleDb-Datenprovider auf den SQL Serverzugreifen, sollten Sie den Aktualisierungscode entsprechend manuellanpassen.

5.10 Datenbindung und Datennavigation

Die Datenbindung in Masken dient dazu, Steuerelemente so mitDatenquellen zu verbinden, dass ausgewählte Inhalte der Daten-quelle in diesen Steuerelementen angezeigt werden und Änderungen,die an Inhalten in den Steuerelementen vorgenommen werden, gege-benenfalls die Datenquelle aktualisieren.

5.10.1 BindingContext

BindingContextDatengebundene Steuerelemente sind keine Neuerung von VisualBasic .NET, sondern waren schon mit ADO(alt) in Visual Basic 6 ver-fügbar. Anders als in Visual Basic 6 ist kein separates ADODataControlzur Datenbindung und zur Navigation in den Datensätzen einerDatenquelle erforderlich, da Visual Studio .NET-Masken ein Binding-Context-Objekt besitzen, das diese Aufgabe übernimmt.

Datenbindung an Datenobjekte, Klassen und Arrays

Im .NET Framework ist eine Datenbindung an alle Objekte möglich,die wie Arrays, Collections oder ADO.NET-Datenobjekte eine IList-Schnittstelle implementieren. Es spielt keine Rolle, ob Sie einADO.NET-Datenobjekt oder eine Objekt-Klasse als Datenquelle wäh-len. Im Prinzip kann jede Eigenschaft eines Steuerelement-Objektesan eine Datenquelle gebunden werden, was unter anderem einedirekte Steuerung des Erscheinungsbildes von Anwendungen durchDatenbankinhalte möglich macht.

Page 63: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

376 ADO.NET und Datenbanken

Es ist wichtig zu verstehen, dass, anders als in einer Recordset-Verar-beitung mit Visual Basic 6, in ADO.NET kein »aktueller« Datensatzeiner Bearbeitungsschleife als Bezug für die Datenbindung mehrererSteuerelemente zur Verfügung steht. Die Bindung von ausgewähltenSteuerelementen an Inhalte aus der gleichen Datenquelle wird überein BindingManagerBase-Objekt bestimmt, das aus dem Binding-Context einer Maske abgeleitet ist. Die Navigation in den Datensät-zen erfolgt über die Position-Eigenschaft des BindingContexts.

Einfache und komplexe Datenbindungen

Datenbindungen für einzelne Steuerelementinhalte einer Maske wer-den der Auflistung der Datenbindungen (DataBindings) durch derenAdd-Methode hinzugefügt. Bei komplexen Datenbindungen wie z.B.dem Füllen eines Dropdowns aus einer Detaildatentabelle werdendessen Bindungen über ein eigenes CurrencyManager-Objekt verwal-tet und angesprochen, auf das der BindingContext verweist.

Listing 5.48 Beispiel für eine einfache Datenbindung

txtGewürzname.DataBindings.Add("Text", _ dsDataSet.Tables("Gewürze"), "Gewürzname")txtGattung.DataBindings.Add("Text", _ dsDataSet.Tables("Gewürze"), "Gattung")

Listing 5.49 Beispiel für eine komplexe Datenbindung

DropDown.DataSource = dvDataViewDropDown.ValueMember = "fkGewürz"DropDown.DisplayMember = "Bildname"DropDown.DataBindings.Add("SelectedValue", _ dsDataSet.Tables("Gewürze"), "pkGewürz")

Beide Bindungstypen lassen sich Steuerelementen zur Entwurfszeitsehr leicht auch im Eigenschaftenfenster der Visual Studio .NET-IDEzuordnen (siehe Abbildung 5.38).

Page 64: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenbindung und Datennavigation 377

Eigenschaften der BindingManagerBase

Ein BindingManagerBase-Objekt hat folgende Eigenschaften:

Methoden der BindingManagerBase

Das BindingManagerBase-Objekt stellt folgende Methoden zur Ver-fügung:

Abbildung 5.38 Zuweisen der Datenbindung in der Visual Studio .NET-IDE

Name Beschreibung

Bindings Ruft die Auflistung verwalteter Bindungen ab

Count Ruft beim Überschreiben in einer abgeleiteten Klasse die Anzahl der Zeilen ab, die von Binding-ManagerBase verwaltet werden

Current Ruft beim Überschreiben in einer abgeleiteten Klasse das aktuelle Objekt ab

Position Ruft beim Überschreiben in einer abgeleiteten Klasse die Position in der zugrunde liegenden Liste ab, auf die an diese Datenquelle gebundene Steuerelemente zeigen, oder legt diese fest

Tabelle 5.28 Eigenschaften des BindingManagerBase-Objekts

Name Beschreibung

AddNew() Fügt beim Überschreiben in einer abgeleiteten Klasse der zugrunde liegenden Liste ein neues Element hinzu

Tabelle 5.29 Methoden des BindingManagerBase-Objekts

Page 65: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

378 ADO.NET und Datenbanken

Ereignisse der BindingManagerBase

Das BindingManagerBase-Objekt löst folgende Ereignisse aus:

5.10.2 Datenmaske mit Bildern

Das Beispiel AccessFormular diente bereits in Abschnitt 5.3, »Datenge-bundene Eingabemaske«, zur Darstellung der Datenbindung und derNavigation in Datensätzen. Es soll an dieser Stelle erweitert werdenund die Anzeige der Bilder ermöglichen, die den Gewürzen in derDatenbank dbWürzen zugeordnet sind. Dabei wird die Format-Methode des Binding-Objektes für das Bild-Steuerelement verwen-det, um die Bilddaten aus der Datenbank zu laden. Ergänzend ist es indiesem Beispiel möglich, vorhandene Bilder zu ersetzen und damitneue Bilder in die Datenbank zu übertragen.

CancelCurrentEdit() Bricht beim Überschreiben in einer abgeleiteten Klasse den aktuellen Bearbeitungsvorgang ab

EndCurrentEdit() Beendet beim Überschreiben in einer abgeleiteten Klasse den aktuellen Bearbeitungsvorgang

GetItemProperties() Ruft die Liste der Eigenschaftenbezeichner für die Datenquelle ab oder legt diese fest

RemoveAt() Löscht beim Überschreiben in einer abgeleiteten Klasse die Zeile am angegebenen Index aus der zugrunde liegenden Liste

ResumeBinding() Setzt beim Überschreiben in einer abgeleiteten Klasse die Datenbindung fort

SuspendBinding() Unterbricht die Datenbindung beim Überschrei-ben in einer abgeleiteten Klasse

Name Beschreibung

CurrentChanged Tritt ein, wenn sich der gebundene Wert ändert

PositionChanged Tritt ein, wenn sich Position geändert hat

Tabelle 5.30 Ereignisse des BindingManagerBase-Objekts

Name Beschreibung

Tabelle 5.29 Methoden des BindingManagerBase-Objekts (Forts.)

Page 66: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenbindung und Datennavigation 379

Beispiel Access-FormularBild

Sie finden das fertige Beispiel AccessFormularBild auf der beiliegendenCD-ROM im Verzeichnis \Kapitel05\AccessFormularBild. Sie könnenauch, wie im Folgenden beschrieben, das Beispielprojekt AccessFor-mular fortsetzen.

Bilder aus der Datenbank

Die Speicherung von Bildern in einer Datenbank galt mit ADO(alt)als abwegige, da brüchige Lösung, die in jedem Fall zu vermeidenwar. In der Regel wurden zu Datensätzen gehörende Bilder alsDateien in eigenen Verzeichnissen gespeichert und in der Daten-bank lediglich die Pfadnamen verwaltet.

Im asynchronen Modell von ADO.NET und unter Berücksichtigungder Fähigkeiten des .NET Frameworks kann auch diese Regel inFrage gestellt werden.

� Nachdem .NET Framework-Anwendungen dynamisch aktuali-sierbar sind und auf mehreren Servern gleichzeitig mit den glei-chen Daten laufen, stellt die Replikation von dateibasierten Bild-daten ein konzeptionelles Hindernis für flexible verteilte Anwen-dungen dar.

� Durch Verwendung der Klassen des .NET Frameworks verringertsich der Aufwand erheblich, Bilder in eine Datenbank zu schrei-ben und sie in einem Datenstrom wieder auszulesen. Siehe dazuauch das folgende Beispiel.

� Das Auslesen von Bildern in den Dateigrößen, wie sie z.B. inWebanwendungen Verwendung finden, verursacht mit aktuel-len Datenbankservern keine Performance-Probleme.

� Mit ADO.NET können Sie auf verschiedene Datenbanktypengleichzeitig zugreifen und deren Daten gemeinsam verarbeiten –es gibt daher mehrere, auch kombinierte Lösungen mit XML-Datenmengen, die eine Speicherung von Bildern in Einzelda-teien überflüssig machen.

Das Speichern von kleinen Bildern in der Datenbank ist, was dieHandhabung, den Aufwand zur Aktualisierung, die Möglichkeitenzum Backup und die direkte Verfügbarkeit betrifft, mit ADO.NETdeutlich gegenüber einer dateibasierten Lösung zu bevorzugen.

Page 67: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

380 ADO.NET und Datenbanken

Datenbindung einrichten

Einige Datenbindungen für die Bilder- und Gewürztabellen sindbereits aus dem vom Assistenten erstellten Beispielprojekt AccessFor-mular vorhanden (siehe Listing 5.50).

Listing 5.50 Vorhandene Datenbindung im Beispielprojekt AccessFormular

Me.BindingContext(objdsWürzen, "tblGewürze")Me.BindingContext(objdsWürzen, "tblBilder")

Fügen Sie in der Entwurfsansicht von DatenFormular aus demAbschnitt Windows Forms der Toolbox ein PictureBox-ElementPictureBox1 hinzu.

Die Bindung für das PictureBox-Steuerelement soll beim Laden desDatenformulars gesetzt werden. Wählen Sie daher aus dem linkenCodenavigations-Dropdown Basisklassenereignisse, dann ausdem rechten Load, um die Ereignisprozedur für das Laden von Daten-Formular anzulegen.

Format-Ereignisnutzen

Tragen Sie in DatenFormular_Load eine einfache Datenbindung fürdie PictureBox1 an das Datenbankfeld tblBilder.Foto ein unddefinieren Sie zwei BindingManagerBase-Objekte für die vorhande-nen Datenbindungen.

Listing 5.51 DatenFormular_Load

Private Sub DatenFormular_Load( _ ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Datenbindung für die PictureBox einrichten PictureBox1.DataBindings.Add("Image", _ objdsWürzen, "tblBilder.Foto") ' Format-Ereignis zum Laden des Bildes einsetzen AddHandler PictureBox1.DataBindings("Image"). _ Format, AddressOf FotoFormatieren ' BindingManagerBase für Hauptdaten einrichten bmbGewürze = Me.BindingContext( _ objdsWürzen, "tblGewürze") ' BindingManagerBase für Detaildaten einrichten bmbBilder = Me.BindingContext( _ objdsWürzen, "tblBilder")End Sub

Page 68: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenbindung und Datennavigation 381

Zur Übertragung der Bilddaten in die PictureBox1 wird im Beispieldas Format-Ereignis des Binding-Objektes genutzt. Dieses Ereignistritt immer dann auf, wenn Daten aus der Datenquelle an ein Steuer-element gesendet und dabei umgewandelt bzw. formatiert werden.Mit Hilfe der Anweisung:

AddHandler PictureBox1.DataBindings("Image"). _ Format, AddressOf FotoFormatieren

wird der Formatierungsvorgang an eine eigene Prozedur Foto-Formatieren delegiert.

Binding-Ereignisse

Ein Binding-Objekt kann folgende Ereignisse auslösen:

Binding-Eigenschaften

Ein Binding-Objekt hat folgende Eigenschaften:

Name Beschreibung

Format Tritt ein, wenn die Eigenschaft eines Steuerele-ments an einen Datenwert gebunden ist

Parse Tritt ein, wenn der Wert eines datengebundenen Steuerelements geändert wird

Tabelle 5.31 Ereignisse des Binding-Objektes

Name Beschreibung

BindingManagerBase Ruft die BindingManagerBase dieser Bindung ab

BindingMemberInfo Ruft ein Objekt mit Informationen über die Bin-dung ab, die auf dem dataMember-Parameter im Binding-Konstruktor basieren

Control Ruft das Steuerelement ab, zu dem die Bindung gehört

DataSource Ruft die Datenquelle für diese Bindung ab

Tabelle 5.32 Eigenschaften des Binding-Objektes

Page 69: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

382 ADO.NET und Datenbanken

FotoFormatieren

Die Prozedur FotoFormatieren wird vom Ereignis Format des Bin-ding-Objektes aufgerufen, wenn der aktuelle Datensatz über diePosition des BindingContexts geändert wird und Bilddaten in diePicturebox1 geladen werden.

Der Aufbau einer Prozedur zur Formatierung von Daten folgt einemeinfachen Prinzip: Die Daten sind im Ereignis-Argument e enthalten,werden in der Prozedur umgewandelt, formatiert und an das Ereignis-Argument e wieder zurückgegeben, mit dem die formatierten Datenschließlich in das Steuerelement gelangen.

Listing 5.52 FotoFormatieren

Public Sub FotoFormatieren( _ ByVal sender As Object, _ ByVal e As ConvertEventArgs) ' Leeres Datenfeld abfangen If Not IsDBNull(e.Value) Then ' EventArgument enthält Byte-Array Dim _img As Byte() = CType(e.Value, Byte()) Dim _ms As New IO.MemoryStream() ' Offset für manche Access Blobs auf 78 setzen Dim _int As Integer = 0 ' Bytes in einen MemoryStream schreiben _ms.Write(_img, _int, _img.Length - _int) ' Bitmap aus MemoryStream erzeugen Dim _bmp As New Bitmap(_ms) _ms.Close() ' Bitmap an EventArgument zurückgeben

e.Value = _bmp End IfEnd Sub

IsBinding Ruft einen Wert ab, der angibt, ob die Bindung aktiv ist

PropertyName Ruft den Namen der Eigenschaft zur Datenbindung des Steuerelements ab oder legt diesen fest

Name Beschreibung

Tabelle 5.32 Eigenschaften des Binding-Objektes (Forts.)

Page 70: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Datenbindung und Datennavigation 383

Die Bilddaten erreichen die Prozedur im Objekt e und können alsArray von Bytes ausgelesen werden. Ziel der Prozedur ist es, diesesByte-Array in ein Bitmap-Objekt umzuwandeln. Dazu bietet es sichan, die Bytes in einen MemoryStream zu schreiben und daraus einBitmap-Objekt zu erzeugen, das am Ende wieder an e übergebenwird.

MemoryStream Die Methode, mit der die Bytes in einen MemoryStream geschriebenwerden, akzeptiert die Argumente offset und count, mit denengesteuert werden kann, bei welchem Byte die Übertragung in denDatenstrom beginnen soll und wie viele Bytes überhaupt übertragenwerden sollen. Die Bilder aus der SQL Server- und der Access-Varianteder Beispieldatenbank dbWürzen benötigen keine Angabe eines Off-set-Wertes. Bei manchen Bildern, die in anderen Access-Datenbankenals OLE-Objekte eingefügt wurden, ist allerdings die Angabe von off-set=78 erforderlich, um die Bilddaten von einem proprietären OLE-Datenheader zu trennen.

Falls die Write-Methode mit dem angegebenen Offset-Wert fehl-schlägt, müssen Sie das Byte-Array eines Bildes bei der Übertragunganalysieren. Setzen Sie dazu in der Zeile mit _ms.Write einen Halte-punkt und starten Sie die Anwendung im Debugmodus. Wenn derHaltepunkt erreicht ist, wählen Sie aus dem Kontextmenü von _imgden Eintrag Schnellüberwachung. Der Beginn der eigentlichen Bitmap-daten ist an der Kennung BM zu erkennen, die als Bytes die Werte 6677 hat. Passen Sie über die Variable _int den Offset-Wert mit derPosition des ersten Bytes der Kennung an.

Nach dem Start der Anwendung und dem Laden der Daten wird daserste Bild geladen. Bei einer Navigation in den Hauptdaten wechseltdas Bild allerdings nicht, da den BindingManager-Objekten der bei-den Tabellen noch die Synchronisation fehlt.

Position synchronisieren

Wählen Sie aus dem linken Codenavigations-Dropdown bmbGewürze,dann aus dem rechten PositionChanged, um die Ereignisprozedur fürdie Navigation in der Haupttabelle anzulegen.

Page 71: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

384 ADO.NET und Datenbanken

Navigations-ereignis Position

Changed

Legen Sie fest, dass beim Wechsel der Position-Eigenschaft derHauptdaten der BindingManager der Detaildaten auf dieselbe Posi-tion weist.

Listing 5.53 Ereignisprozedur für den Wechsel der Position

Private Sub bmb_PositionChanged( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles bmbGewürze.PositionChanged ' Aktuelles Bild anzeigen bmbBilder.Position = bmbGewürze.Position ' Bild ist dann vorhanden, wenn beide ' BindingManager auf denselben Datensatz zeigen If bmbGewürze.Current.row.Item("pkGewürz") <> _ bmbBilder.Current.row.Item("fkGewürz") Then PictureBox1.Visible = False Else PictureBox1.Visible = True End IfEnd Sub

Da nicht jedem Gewürz ein Bild zugeordnet ist, sollte diePictureBox1 nur dann sichtbar sein, wenn die BindingManager bei-der Tabellen auf denselben Datenschlüssel in der Hauptdatentabellezeigen.

Abbildung 5.39 Anzeige von Bildern aus der Datenbank

Page 72: Stefan Fellner Visual Basic .NET und Datenbanken · Inhalt 5 Inhalt Einleitung 13 Ein Neubeginn mit Visual Basic .NET 14 Update oder Neuschöpfung? 14 Die neue Datenbanktechnologie

Hierarchische Daten 385

Neues Bild laden

Der Vollständigkeit halber folgt der Code zum Laden eines neuen Bil-des, das durch Klick auf btnLaden ausgelöst wird.

Fügen Sie der Maske in der Entwurfsansicht aus der Toolbox einOpenFileDialog-Objekt hinzu, über dessen Filter-Eigenschaft Sie inder Code-Ansicht den zu wählenden Dateityp vorgeben können.

Listing 5.54 Das Laden eines neuen Bildes über einen Datei-Öffnen-Dialog

Private Sub btnBildLaden_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnBildLaden.Click ' Bitmap mit Dateidialog auswählen With OpenFileDialog1 .CheckFileExists = True .Filter = "Datendateien (*.jpg)|*.jpg" If .ShowDialog = DialogResult.OK Then ' Bitmap-Datei as Stream laden Dim _st As System.IO.Stream = .OpenFile Dim _img As New Bitmap(_st) PictureBox1.Visible = True PictureBox1.Image = _img End If End WithEnd Sub

Nach der erfolgreichen Auswahl einer Bilddatei wird diese von derOpenFile-Methode als Datenstrom geöffnet und daraus ein Bitmap-Objekt erzeugt. Die Zuweisung der Bitmap an das SteuerelementPictureBox1 fügt dieses über die Datenbindung auch in die Daten-tabelle ein und wird über Aktualisieren in die Datenbank übertragen.

5.11 Hierarchische Daten

Verknüpfte Tabellen im DataGrid

Wie in Abschnitt 5.8, »Tabellenverknüpfungen«, gezeigt wurde, ist esnicht schwer, ein DataGrid an verknüpfte Tabellen zu binden, um indiesen zu navigieren. Die Darstellung von Datenhierarchien in einemDataGrid ist jedoch sehr eingeschränkt, da jeweils nur die Daten einerTabelle anzeigt werden und kein Überblick über alle untergeordnetenDatensätze in einer Hauptdatentabelle möglich ist.