Date post: | 05-Apr-2015 |
Category: |
Documents |
Upload: | kolman-heintzelman |
View: | 110 times |
Download: | 4 times |
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
Managed ProviderManaged Provider
Data-Data-AdapterAdapter
DataReaderDataReader
CommandCommandConnectionConnection
XmlReaderXmlReader
XmlText-XmlText-ReaderReader
XmlNode-XmlNode-ReaderReader XmlDocumentXmlDocumentTextReaderTextReader
StringString StreamStream
<xml><xml>……
</xml></xml>
““<xml><xml>……
</xml>”</xml>”
myDataSetmyDataSet
ItemItem
CustCustOrderOrder
Web/Windows Web/Windows Form ControlsForm ControlsVS .NET VS .NET
DesignersDesignersVS .NET Class VS .NET Class
GeneratorGenerator
ADO vs ADO .NETein Ü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 Data storestore
DataDataProviderProvider
Einbindung in die Objekthierarchie
...System.DataSystem.Data.OleDbSystem.Data.SqlClient...
System.Data
DataSet
DataTable
DataColumn
DataRow
DataSetView
DataRelation
System.Data.OleDb
OleDbCommand
OleDbDataReader
OleDbDataAdapter
OleDbParameter
OleDbErrors
OleDbConnection
...
System.Data.SqlClient
SqlCommand
SqlDataReader
SqlDataAdapter
SqlParameter
SqlErrors
SqlConnection
...
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
// Angabe des Namespace (System.Data.SQL)// Angabe des Namespace (System.Data.SQL)Using System.Data.SqlClient;Using System.Data.SqlClient;
// Instanziieren eines SQLConnection Objekts// Instanziieren eines SQLConnection ObjektsSqlConnection cnn = new SqlConnection();SqlConnection cnn = new SqlConnection();
// Connection String setzen// Connection String setzencnn.ConnectionString = cnn.ConnectionString = "server=localhost;uid=sa;database=pubs";"server=localhost;uid=sa;database=pubs";
// Öffnen der Connection// Öffnen der Connectioncnn.Open();cnn.Open();
Connection Objekt
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
// 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";
Command Objekt
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 DefinierenIDataReader dr;
// Kommando ausführencmd.Execute(out dr);
// Ergebnisse auslesenwhile(dr.Read()){
Console.WriteLine("Name = " + dr["au_lname"]);}
// Connection schließencnn.Close();
DataReader Verwendung
DataSet Common client data store Relationale Sicht der Daten
• Tabellen, Spalten, Zeilen, Beschränkungen, Beziehungen
Direkte Erzeugung von Metadaten einfaches Einfügen von Daten
Explizites Cache Modell• Disconnected, remotable Objekt
• Hat keine Kenntnis über die Datenquelle oder deren Eigenschaften
• Zugriff wie auf ein Array
• Strong Typing möglich
DataSetDataSet
TablesTables
TableTable
ColumnsColumns
ColumnColumnConstraintsConstraints
ConstraintConstraintRowsRows
RowRowRelationsRelations
RelationRelation
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//Ausgabe jedes Autors und dessen Titel foreach (Author myAuthor in Pubs.Authors.Rows) foreach (Author myAuthor in Pubs.Authors.Rows) {{ Console.WriteLine("Name = " + myAuthor.au_lname);Console.WriteLine("Name = " + myAuthor.au_lname); foreach (Title myTitle in myAuthor.Titles)foreach (Title myTitle in myAuthor.Titles) {{
Console.WriteLine("Title = " + myAuthor.Title);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ügungDataColumn.AutoIncrementSeed/.AutoIn
crementStep müssen gesetzt werdenAutoNumber-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"
pk="prodID"/><column name="total" type="System.Double"
expression="qty*price"/></table><column name="total" type="System.Double„
expression="sum(child(lineItems).total)"/></table><table name="comm" basetable="customercommunication"
fields="telID, custID, tel" pk="telID"/></table>
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...Uff...
ADO .NET Quellen
Jetzt lerne ich ADO.NETRalf Westphal, 400 Seiten, Markt+Technik, 2002 (noch nicht erschienen)
ADO .NET for the ADO Programmerhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/adonetdev.asp
ADO.NET : Migrating from beta 1 to beta 2http://www.asptoday.com/content/articles/20010802.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK
Coping with a New Beta - Connecting to Databaseshttp://www.dotnetjunkies.com/tutorials.aspx?tutorialid=81
Coping with a New Beta - DataSetCommand to DataAdapterhttp://www.dotnetjunkies.com/tutorials.aspx?tutorialid=83
Using ADO+ and C# in the .NET Framework - Part 1http://www.asptoday.com/content/articles/20000925.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK
Using ADO+ and C# in the .NET Framework - Part 2http://www.asptoday.com/content/articles/20000925.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK
Revisiting the Use of ADO in .NET Applicationshttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data08092001.asp
Commands in ADO .NEThttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data07262001.asp
Data Relations and Relativeshttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data07122001.asp
Views and Filtershttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndive/html/data06142001.asp
Paradigmenwechsel mit ADO.NEThttp://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 kompakt140 Seiten, Spektrum Akademischer Verlag, 2002, ISBN 3827411858
Jetzt lerne ich ADO.NETEinfache Datenbankprogrammierung im .NET- Framework400 Seiten, Markt+Technik, 2002, ISBN 3827262291 (erscheint Mitte 2002)
Empower peopleEmpower people
through great through great softwaresoftware
any time, any place,any time, any place,
and on any deviceand on any device