ADO.NET Ralf Westphal Freier Fachautor & Berater MSDN Regional Director [email protected] Ausgangsfrage  Wie wollen Sie in OO-Programmen auf Ihre Daten zugreifen? • • Per relationalem Datenzugriffs-API • Cursor, Join etc. Per Objektmodell • Objekte,

Download Report

Transcript ADO.NET Ralf Westphal Freier Fachautor & Berater MSDN Regional Director [email protected] Ausgangsfrage  Wie wollen Sie in OO-Programmen auf Ihre Daten zugreifen? • • Per relationalem Datenzugriffs-API • Cursor, Join etc. Per Objektmodell • Objekte,

ADO.NET

Ralf Westphal Freier Fachautor & Berater MSDN Regional Director [email protected]

Ausgangsfrage

Wie wollen Sie in OO-Programmen auf

• •

Ihre Daten zugreifen?

Per relationalem Datenzugriffs-API Cursor, Join etc.

Per Objektmodell Objekte, „Collections“, Hierarchien

Sind Datenbanksysteme nötig?

 

Kann Datenverwaltung nicht über

• • •

Objektmodelle stattfinden?

Intuitive Abbildung der „realen Welt“ Einfache zu Traversieren/Manipulieren 1 Datenmodell für persistente Daten und in memory Datenverwaltung, statt 2

• • • •

Probleme Persistenz Abfragen Gleichzeitiger Zugriff Große Datenmengen

Lösungen

 • • • •

Lösungen für mögl. Probleme mit Objektmodellen für die Datenhaltung

Persistenz Serialisierung (.NET Formatter)

• •

Abfrage Deklarative Abfragesprache Meta-Objektmodell

• •

Gleichzeitiger Zugriff (Objektmodell-)Server Clients cachen Daten

Große Datenmengen Server mit beliebiger interner Datendarstellung

Fazit

   •

Datenbanken sind notwendig

Wertvolle Dienstleistungen Transaktionen, gleichzeitiger Zugriff, Verwaltung großer Datenmengen, Replikation usw.

Objektmodelle stehen nicht im Gegensatz zu Datenbanken

• •

Wir brauchen...

ein vernünftiges Meta-Objektmodell ein zum Meta-Objektmodell passenden Datenbankzugriffs-APIs

ADO.NET Grundlagen

ADO.NET Architektur

VS .NET Designers Web/Windows Form Controls VS .NET Class Generator “ String Stream TextReader myDataSet Cust Order Item Managed Provider Data Adapter DataReader Command Connection XmlReader XmlText Reader XmlNode Reader XmlDocument

ADO vs ADO .NET

ein Überblick der Änderungen

      

COM Marshalling Connection oriented OLE DB Provider Zwei mögliche

• •

Programmiermod.: ADO OLE DB nativ Cursor Joins für > 1 Tabelle Datentypen von COM/COM+ abhängig

      

COM+, Datasets Disconnected Access Managed Providers

• •

Ein Modell: Managed Provider (connected Layer) DataSet (discon.) (Kein Cursor) Kein Join notwendig XML, keine Datentypen Konvertierung nötig

Managed Providers

  

Interaktion mit Datenquellen „managen“

Äquivalent des OLE DB Layers Direkte Darstellung des Consumer Interfaces (nicht mehr mit der Zweiteilung COM/Automation)

• • •

Aktuelle Implementierungen

OleDB Managed Provider (ähnlich ADO) Zugriff auf beliebige OLE DB Provider SQLServer Managed Provider

• •

Weitere folgen ODBC SQL XML Data Provider

Data store

Einbindung in die Objekthierarchie System.Data

DataRelation DataSet DataTable DataRow DataColumn DataSetView ...

System.Data

System.Data.OleDb

System.Data.SqlClient

...

System.Data.OleDb

System.Data.SqlClient

OleDbConnection OleDbCommand OleDbDataReader OleDbParameter OleDbDataAdapter OleDbErrors SqlConnection SqlCommand SqlDataReader SqlParameter SqlDataAdapter SqlErrors

ADO.NET Objekt Model

  • •

Das klassische ADO Gewand … Connection Command, Parameter

• • •

… mit neuen Objekten:

DataReader Forward-only, Read only „Recordset“

DataSet Disconnected, In-Memory Cache

DataAdapter Verbindet das DataSet mit der Datenquelle

Connection Objekt

  

Repräsentation einer Verbindung zu einer Datenquelle

• •

Mit einer Connection ist es möglich … Die Verbindung zur Datenquelle anzupassen Transaktionen zu handhaben (Begin, Commit, Abort) Ähnlichkeiten zum ADODB.Connection Objekt sind nicht unerwünscht

Connection Objekt

// Angabe des Namespace (System.Data.SQL) Using System.Data.SqlClient; // Instanziieren eines SQLConnection Objekts SqlConnection cnn = new SqlConnection(); // Connection String setzen cnn.ConnectionString = "server=localhost;uid=sa;database=pubs"; // Öffnen der Connection cnn.Open();

Command Objekt

    •

Stellt ein auszuführendes Kommando dar Nicht unbedingt ein SQL Kommando

• • •

Mit dem ADO .NET Command Objekt ist es möglich: Ein Statement, welches auf dem Server ausgeführt werden soll, zu definieren Parameter Informationen für dieses Kommando anzugeben Rückgabewerte nach der Kommandoausführung zu erhalten Wie das ADODB.Command Objekt

Kann Parameter enthalten Werte, die bei Ausführung eines Statements genutzt werden können

Command Objekt

// Create Command SqlCommand cmd = new SqlCommand(); // Aktive Connection des Kommandos und Inhalt setzen cmd.ActiveConnection = cnn; cmd.CommandText = "Select au_lname from authors where state = @param1"; // Parameter erzeugen und Werte setzen cmd.Parameters.Add( new SQLParameter("@param1", typeof(String),2) ); cmd.Parameters["@param1"].Value = "CA";

DataReader

    •

Der DataReader bietet einen forward-only, read-only Datenstrom Stellt die Ergebnisse einer ausgeführten Abfrage/Kommandos dar

Der DataReader bietet die Möglichkeit … Einen Ergebnis-Datenstrom von einer Datenquelle zu erhalten

• •

Gleichbedeutend mit einem FO/RO RecordSet Unterstützt jedoch weder Scrolling noch Updates

Auf Felder greift man am besten mit Hilfe von Accessoren (strongly typed, indexed) zu, die FieldsCollection ist die schlechtere Möglichkeit Performance

• 

myRow.GetInt(0) Zugriff über den Feldnamen (einfache Nutzung/Kompatibilität)

myRow["fieldname"] Unterstützung von DataBinding in WebForms

DataReader Verwendung

// DataReader Definieren IDataReader dr; // Kommando ausführen cmd.Execute(out dr); // Ergebnisse auslesen while(dr.Read()) { Console.WriteLine("Name = " + dr["au_lname"]); } // Connection schließen cnn.Close();

DataSet

Common client data store

  

DataSet

Relationale Sicht der Daten Tabellen, Spalten, Zeilen, Beschränkungen, Beziehungen Tables Table Columns Column Constraints

• •

Direkte Erzeugung von Metadaten einfaches Einfügen von Daten Zugriff wie auf ein Array Strong Typing möglich Rows

• •

Explizites Cache Modell Disconnected, remotable Objekt Relations Relation Hat keine Kenntnis über die Datenquelle oder deren Eigenschaften Constraint Row

DataSet

// Erzeugen eines DataSet "PublicSet" DataSet pubs = new DataSet(" PublicSet"); //Erzeugen einer Tabelle “bestand" DataTable inventory = new DataTable(“bestand"); inventory.Columns.Add(“kennzeichenID",typeof(Int32)); inventory.Columns.Add(“menge",typeof(Int32)); // Tabelle “Bestand” zum DataSet PublicSet hinzufügen pubs.Tables.Add(bestand); // Datensatz zur Bestandstabelle hinzufügen DataRow row = bestand.NewRow(); row[“kennzeichenID"]=1; row[“menge"]=25; bestand.Rows.Add(row);

(Strongly) Typed DataSet

DataSets, Tabellen, Zeilen als Objekte nutzen

Spalten und Beziehungen als Eigenschaften //Ausgabe jedes Autors und dessen Titel foreach (Author myAuthor in Pubs.Authors.Rows) { Console.WriteLine("Name = " + myAuthor.au_lname); foreach (Title myTitle in myAuthor.Titles) { Console.WriteLine("Title = " + myAuthor.Title); } }

DataAdapter

 • • •

Weiß, wie eine Tabelle aus der Datenbank geladen wird und schreibt Änderungen zurück

Fill(DataSet)

Update(DataSet) Mapping zwischen Tabellen und Spalten

• •

Benutzer kann die voreingestellten Kommandos überschreiben (insert/update/delete) z. B. um Stored Procedures anzugeben Default-Kommandos mit CommandBuilder erzeugen Erlaubt es, ein DataSet aus mehreren Datenquellen zu füllen

DataAdapter

// Neues DataSetCommand SqlDataAdapter dsAdap = new SqlDataAdapter( "Select * from authors",cnn); // Daten an ein DataSet übergeben dsAdap.Fill(pubs, "Authors"); // Änderungen in den Kundendaten des DataSets durchführen und Update durchführen pubs.Tables["Authors"].Rows[0]["au_lname"]="smith"; SqlCommandBuilder bld = new SqlCommandBuilder(dsAdap); dsAdap.Update(pubs, "Authors");

DataBinding

  • • • •

DataView Wie ein View auf eine Tabelle Erlaubt, Sortierreihenfolge und Filter in einem View einer Tabelle festzulegen Beliebige DataViews können von einer Tabelle erzeugt werden, um unterschiedliche Views der gleichen Tabelle möglich zu machen Wird für das DataBinding verwendet

• • • •

DataSetView Wie ein View, daß auf einem DataSet aufsetzt Sortierreihenfolge und Filter lassen sich setzen Erlaubt das Verbinden von DataViews Wird für das Databinding verwendet

DataBinding

 • • • • • • • • •

Als Quelle für DataBinding dienen: (DataReader) DataTable DataView DataSet DatSetView Array Collection IList IEnumerable

Zusammenfassung

   

ADO .NET ist die natürliche Weiterentwicklung

• •

von ADO Bekanntes Connection/Command Modell

• •

Teilung von Persistenz und Programmierung Optimierter ForwardOnly/ReadOnly Ergebnis-Datenstrom Expliziter, nicht verbundener relationaler Cache ADO .NET ist XML optimiert

ADO .NET ist im .NET Framework integriert Exception Handling, Namensgebung, Notierung Bessere plattformübergreifende Zusammenarbeit und Sharing der Daten, bessere Skalierbarkeit, strong typing

ADO.NET Anwendungen

Überblick

 • • •

Szenen eines Datenzugriffs

• • •

Aufwärmen: AutoNumber-Felder Logisches Löschen Joins & DataSets

• •

Jetzt wird es ernst: Hierarchische Daten laden Logisches Sperren

Cool down: Eigene Datenquellen anbinden

AutoNumber-Felder

AutoNumber-Information wird nicht autom. geladen

Steht erst nach DataAdapter.FillSchema zur Verfügung

DataColumn.AutoIncrementSeed/.AutoIn

crementStep müssen gesetzt werden

AutoNumber Werte in DataTable können nicht in AutoNumber-DB-Felder persistiert werden

Fremdschlüssel geraten aus dem Tritt

Fazit: AutoNumber-Felder vermeiden!

Logisches Löschen

 

Ein Datensatz wird im DataSet gelöscht, in der Datenbank jedoch nur als gelöscht markiert

• •

Lösung: Tabelle mit einer Spalte für ein Löschkennzeichen ausstatten

DataAdapter mit speziellem Löschkommando ausstatten Update mytable set delFlag=@delFlag where pk=@pk

Joins & DataSets

  

Einsatz bisher

Anbinden von untergeordneten Informationen (Master/Detail)

Anbinden von Lookup-Informationen Kein (semi)automatischer Update

CommandBuilder generiert keine DML Anweisungen für DataTables mit mehreren Tabellen

Das ist gut so!

Einsatz mit DataSets

Untergeordnete Informationen über Relationen anbinden

Es müssen mehrere Select-Anweisungen ausgeführt werden

Where-Klauseln untergeordneter Select Anweisungen müssen Where Klauseln übergeordneter enthalten

Lookup Informationen entweder auch über Relationen oder weiterhin über Joins anbinden

Fazit: Joins verlieren mit DataSets an Bedeutung

Joins sind oft keine natürliche Darstellung von Datenbeziehungen

Hierarchische Daten laden

  • •

Hierarchische Daten bilden oft eine logische Einheit: „Dokumente“ DB APIs kennen keine „Dokumente“ Daten in „Dokument“-Granularität zu laden, entlastet Netzwerkverbindungen

• • •

CRUD-Szenarien profitieren vom Denken in „Dokumenten“ „Dokumente“ definieren...

Zugriff per „Dokument“-ID (PK des Wurzeldatensatzes) „Dokumente“ mit eigenem API verwalten...

Hierarchische Daten laden

Hierarchische Daten laden

Mögliche „Dokument“-Definition < table name="customer" basetable="customers" fields="*" pk="custID" checkOutOk="1"> < table name="invoices" basetable="invoices" fields="*" pk="invID" checkOutOk="1"> < table name="lineItems" basetable="invoiceLineItems" fields="*" pk="invLIID"> < lookup basetable="products" fields="description, price" < column pk="prodID"/> name="total" type="System.Double" expression="qty*price"/> < column name="total" type="System.Double„ expression="sum(child(lineItems).total)"/> < table name="comm" basetable="customercommunication" fields="telID, custID, tel" pk="telID"/>

Hierarchische Daten laden

  • • • •

Rudimentärer „Dokument“-API DataSet CreateDocument() DataSet GetDocument(string id) StoreDocument(doc as DataSet) DeleteDocument(string id)

• • • •

ToDos „Dokument“-Definition zuordnen DB-Anbindung Validation?

Logisches Sperren?

Logisches Sperren

  

Sperren von Datensätzen während einer (lange andauernden) Bearbeitung Probates Mittel: physikalisches Sperren

• •

via DB-API

Das ist immer falsch!

ADO.NET bietet dafür keine Mittel

Lösung: Logisches Sperren Sperrungen werden durch Anwendung

verwaltet Z.B. im Hauptspeicher, spezielle Tabelle

Logisches Sperren

 • • • •

Herausforderungen Sicherstellen, dass alle Beteiligten die

logischen Sperren beachten Datenzugriff darf nicht mehr direkt stattfinden, sondern nur über einen dedizierten API Wer (ent)sperrt wann?

Was passiert mit „zu lange“ gesperrten

Daten?

Z.B. weil der Client abgestürzt ist Performantes Sperren vs „dauerhaftes“ Sperren

Eigene Datenquellen anbinden

   • •

DataSets werden über Managed Provider gefüllt DataSets sind unabhängig von Datenquellen Managed Provider sind nicht auf Datenbanken festgelegt

• • •

Managed Provider Klassen Datenquelle anbinden/manipulieren: Connection, Command Datenquelle lesen: DataReader, DataAdapter Datenquelle aktualisieren: DataAdapter

A Simple Managed Provider

Realisierung eines eigenen DataAdapter ist ausreichend Implementiert IDataAdapter

Fazit

  • • • •

ADO.NET zwingt zum Umdenken

Es gibt (fast) keine Cursor mehr DataReader ist heute eine „Ausnahme“ DataSets sind in-memory Datencaches DataSets unterstützen eine oft natürlichere Sicht auf Daten

ADO.NET bietet kaum „Infrastruktur“ für einige typische Probleme „Dokument“-Handling

SQL XML .NET Klassen mögen helfen

Logisches Sperren Die Zukunft?

ResultSets

ObjectSpaces: OR-Mapping

Fragen!?

Uff...

ADO .NET Quellen

           

Jetzt lerne ich ADO.NET

Ralf Westphal, 400 Seiten, Markt+Technik, 2002 (noch nicht erschienen) ADO .NET for the ADO Programmer http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/adonetdev.asp

ADO.NET : Migrating from beta 1 to beta 2 http://www.asptoday.com/content/articles/20010802.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l 7LCYvBGK Coping with a New Beta - Connecting to Databases http://www.dotnetjunkies.com/tutorials.aspx?tutorialid=81 Coping with a New Beta - DataSetCommand to DataAdapter http://www.dotnetjunkies.com/tutorials.aspx?tutorialid=83 Using ADO+ and C# in the .NET Framework - Part 1 http://www.asptoday.com/content/articles/20000925.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l 7LCYvBGK Using ADO+ and C# in the .NET Framework - Part 2 http://www.asptoday.com/content/articles/20000925.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l 7LCYvBGK Revisiting the Use of ADO in .NET Applications http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data08092001.asp

Commands in ADO .NET

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data07262001.asp

Data Relations and Relatives http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data07122001.asp

Views and Filters http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data06142001.asp

Paradigmenwechsel mit ADO.NET

http://www.microsoft.com/germany/ms/msdnbiblio/kolumne/062001rw.htm

Über den Referenten

Ralf Westphal ist freier Softwaretechnologievermittler. Er arbeitet als Fachautor, Coach/Berater, Softwareentwickler und Sprecher auf Konferenzen im In- und Ausland wie Microsoft Technical Summit, XML-in-Action, BASTA!, COMDEX, Software Development oder XML One. Der Schwerpunkt seiner Arbeit liegt bei der Vermittlung und Anwendung moderner Softwaretechnologien und -konzepte auf der Microsoft Plattform mit Fokus in den Bereichen OOP/komponentenorientierte Entwicklung, Softwarearchitektur und .NET Framework.

Darüber hinaus ist Ralf Westphal einer der deutschen Microsoft MSDN Regional Directors, Mitglied verschiedener Fachbeiräte und war von 1998 bis 2001 Chefredakteur der Visual Basic Fachzeitschrift BasicPro.

Bücher des Referenten

.NET kompakt

140 Seiten, Spektrum Akademischer Verlag, 2002, ISBN 3827411858

Jetzt lerne ich ADO.NET

Einfache Datenbankprogrammierung im .NET Framework

400 Seiten, Markt+Technik, 2002, ISBN 3827262291 (erscheint Mitte 2002)

Empower people through great software any time, any place, and on any device