ASPNL logo (1 kb)
zaterdag 17 mei 2008




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

Overzicht van ADO.NET

Door Charles Carroll
24 januari 2002

Ik vind de aanpak van ADO.NET fantastisch; In het begin vond ik het vreselijk, totdat ik het hele plaatje begreep. Het kost echter best wat moeite om te begrijpen hoeveel ADO.NET verbetert, dus haak niet te snel af.

Het verleden: De ADO manier van records lezen

ASP -> ADO -> Database (of een andere data source):

rs.Open
Do Until rs.EOF
   Response.Write("Naam")
       rs.MoveNext
Loop
rs.Close

bestond uit een heleboel opdrachten aan de database, meer dan de meeste mensen zich realiseren. Laten we dit van dichtbij bekijken, waarbij we er van uit gaan dat we 300 records ophalen met vier velden:

  • rs.Open is +1 opdracht
  • rs.EOF test is +300 opdrachten
  • Elke veld dat opgehaald wordt is minimaal 1 opdracht (300x4 = 1200 opdrachten)
  • rs.MoveNext is +300 opdrachten
In totaal resulteert de bovenstaande code dus in ongeveer 1800 opdrachten aan de database, die mogelijk zelfs over het netwerk gaan (hoewel de cachesize eigenschap het aantal opdrachten kan verminderen in ruil voor server geheugen en een dure recordset cursor). Dit is waarom ik fanatiek het gebruik van Getrows and Getstring aanbeval voor ADO, zie Data ophalen met Getrows.

En nog een andere opmerking:

  • Opdrachten zoals rs("Naam") vragen waardes op uit de database (via het netwerk) en retourneren die in het data type Variant, die vervolgens dus nog geconverteerd moet worden naar het juiste data type.
  • Opdrachten zoals rs("Naam").Type vragen het data type van het veld op uit de database (via het netwerk). Het resultaat hiervan kan erg verschillen, ook per database (bijvoorbeeld sybase datum, oracle datum, etc.).

Er gebeurt nog veel meer onder de kap dan de meeste mensen zich realiseren, zie: GetRows! ... Don't retrieve data any other way!.
En aangezien COM de data vast moet houden en converteren naar VB6, C++, of data types in andere programmeertalen (die het er niet mee eens zijn wat een integer of string is) wordt een dataset als volgt opgeslagen in het geheugen.

De datatype in een recordset volgens de programmeur
  veld 1 veld 2 veld 3
record 1 integer string datum
record 2 integer string datum
record 3 integer string datum
record 4 integer string datum
record 5 integer string datum

COM Realiteit
  veld 1 veld 2 veld 3
record 1 variant variant variant
record 2 variant variant variant
record 3 variant variant variant
record 4 variant variant variant
record 5 variant variant variant

Varianten nemen natuurlijk meer geheugen in dan sterk getypeerde data en brengt een conversie last met zich mee.

De ADO.NET manier van records lezen

ASP --> ADO.NET -> DataSet:
Database openen
Data overzetten van database naar dataview in een dataset
Geen Until... Loop

De dataview bevat de data en de connectie wordt gesloten. Elke interactie vindt nu plaats met deze tabel in het geheugen, een dataview in een dataset. De .NET onderdelen zorgen ervoor dat:

  • rs("Naam") heeft GEEN interactie met de database (via het netwerk). De waarde wordt direct uit de dataview in het geheugen gelezen. Deze waarde is daarom sterk getypeerd.
  • rs("Naam").Type haalt sterk getypeerde data uit de dataset, onafhankelijk van de database types.
  • De waarden in de dataset zijn sterk getypeerd, dus nemen ze weinig geheugen in. Er is geen conversie nodig om de data te gebruiken.

Zodra de data in de dataset zit, fungeert de dataview als een tabel/query uit de database, maar is deze onafhankelijk van de bron, en heb je dus ook niet te maken met de eigenaardigheden van de bron. Aangezien gemengde data bronnen, arrays en dergelijke allemaal gepresenteerd worden in een dataset, is het makkelijk om te sorteren en filteren, en om gecombineerde queries te doen op data uit verschillende bronnen. Een dataview in een dataset kan opgevuld worden met data uit:

  • een Oracle database
  • een SQL Server database
  • een Access database
  • XML bestanden
  • een multidimensoniale array

Dataviews hebben handige eigenschappen die arrays normaal gesproken niet hebben -- Je kunt ze filteren en sorteren, en SQL queries kunnen uitgevoerd worden op de dataviews die zich in het geheugen bevinden (niet langer in de database). Verder zijn dataviews sterk getypeerd, daar waar arrays in ASP bestaan uit data van het type Variant, hetgeen coversielast met zich mee brengt.

Belangrijk: Als je in ADO vroeg om een veld/record data onderdeel dan was dit een Variant. In ADO.NET zijn Datasets waarden sterk getypeerd (integer, datum, string, etc.) en waardoor ze minder geheugen gebruiken. In ADO resulteerde een verzoek als "geef me de veldname" of "geef me het veld type" (bijvoorbeel: rs("Naam").Type, rs("Naam").DefinedSize, rs(2).Name, rs.RecordCount) in een database opdracht met het daarbij behorende database verkeer. ADO.NET vraagt deze dingen gewoon aan de dataview, en niet aan de achterliggende database. Hierdoor wordt zeer veel database verkeer vermeden. GetRows and Getstring zijn dus niet nodig in deze omgeving.

Een andere gemak is dat een dataset meerdere dataviews kan bevatten, hetgeen ADO code elimineert waarin er tegelijkertijd meerdere recordsets open zijn. Data van acht gegevensbronnen kan in acht verschillende dataviews opgeslagen worden, die deel uitmaken van één dataset. En aangezien de data in een dataset wordt opgeslagen als XML, als het geplaatst is in het geheugen, in een cache, in een sessie variabele, of een applicatie variabele applicatie scope, draagt het nooit de extra bagage van een database verbinding. Alleen de data wordt in het geheugen opgeslagen.

ADO mengt opmaak en code, ADO.NET doet dat niet!

Je kunt een sjabloon binden aan een dataset, zodat de data in de dataset wordt weergegeven volgens dat sjabloon.
Easy Grid Display from Access/OLEDB Databases by Charles Carroll
DataGrid and Column Binding by Charles Carroll
Radio Button/Check Box Lists from Databases by Charles Carroll
Dropdown Lists from Database by Charles Carroll
laat een aantal manieren zien om een dataset op te maken, zonder dat daarbij constructies als Until ... Loop gebruikt worden. Deze voorbeelden gebruiken specifiek niet een dataset, maar er is gekozen voor het DataReader object aangezien geen van de datasets mogelijkheden (en overhead) nodig is. Het DataReader object is daarom in deze situaties handiger.

ASP.NET Quickstart: Data Binding Server Controls
ASP.NET Quickstart: Data Access and Customization
laat veel meer voorbeelden zien van het weergeven van data uit een database zonder loops, maar verbonden aan datasets.

Visual Inheritance/CBF by Charles Carroll
laat zelfs zijn hoe de lelijkheid van ADO code tussendoor wordt opgelost door presentatie en het scheiden van code.

3: Data terugplaatsen

In ADO waren er een aantal manieren om data in een database te plaatsen:

  • met rs.AddNew, een opdracht die de staat van de data moet bijhouden
  • met een SQL opdracht die INSERT INTO gebruikt
  • via een batch (groepsgewijze) update

Een aantal van deze mogelijkheden eiste expliciete server cursors, locks, en lelijke details. Batch updates waren alles of niets. Als je bijvoorbeeld 50 records wilde verplaatsen en één daarvan kon niet verplaatst worden dan werd de gehele batch geweigerd en werden er dus geen records verplaatst.

Al het verkeer tussen ADO en de achterliggende data bron gebeurde constant en was "nauw verbonden" code met server cursors, lock types, etc. Een laag-niveau onderzoek van de onderliggende conversatie zou lelijke details tonen.

Het was allemaal nauw verbonden met de driver en werkte niet meer bij driver updates, als een andere soort data bron gebruikt werd (bijvoorbeeld Oracle i.p.v. SQL Server), etc. Over het algemeen waren recordset operaties/code geneigd niet meer te werken elke keer als de data bron of driver veranderde.

In ADO.NET heeft elke dataset rij een RowError eigenschap. Alle records in een batch worden verwerkt door de achterliggende data bron. ALLEEN de records waarvoor de operatie mislukt, krijgen de RowError eigenschap, voor de rest van de records is de operatie gewoon gelukt.

Al het verkeer tussen ADO.NET datasets en de data bron gaat in principe via XML. Hierdoor kan het gewoon door een firewall en zijn er nog tal van andere voordelen/neveneffecten. RDS communiceerde vanuit Internet Explorer over Poort 1443 met SQLserver. Nu communiceert ADO.NET met XML over poort 80 waardoor firewalls niet tussen beide kunnen komen!

In feite weet ADO.NET hoe het
INPUT DATA als parameters neemt--> ADO.NET genereert XML/SQL -> geeft aan de back-end
DELETE --> ADO.NET genereert XML/SQL -> geeft aan de back-end
etc.

Server-Side Data Access geeft hier een voorbeeld van.

Deze datasets vragen nogal wat werk van de server. Eigenlijk is elke dataset een soort kleine database. Relaties kunnen worden bewerkstelligd tussen tabellen/datasets, kolommen kunnen worden toegevoegd en tabellen kunnen "on the fly" worden toegevoegd.

Je kunt met ADO.NET dus een hele set met gerelateerde data maken, en meerdere records in verschillende tabellen toevoegen, wijzigen en verwijderen. Ook kun je relaties tussen tabellen aanleggen enz. Dit alles gebeurt ZONDER dat er met de achterliggende data bron (bijvoorbeeld een Oracle of SQL Server database) gewerkt wordt. Pas als je klaar bent kun je in één keer de achterliggende data bron(nen) bijwerken. Voorheen (in ADO), moest je voor elk record dat je toevoegde, wijzigde of verwijderde communiceren met de achterliggende data bron.

Jouw code kan bijvoorbeeld tal van records maken in verschillende tabellen, records aanpassen, records verwijderen zonder dat er interactie met de back-end plaatsvindt. Elke vraag aan de dataview/dataset (Hoeveel records zijn het? Hoeveel rijen zijn gerelateerd aan deze andere tabel? Wat is de sleutel van het record dat ik net heb toegevoegd?) is lokaal, en heeft geen interactie met de back-end tot gevolgd.

DIt is slechts het topje van ijsberg (zoals Scott Guthrie zou zeggen), maar het geeft je wel een idee van een aantal concepten in ADO.NET die veel voordelen hebben voor de schaalbaarheid en het verbuik van bandbreedte.

© Charles Carroll (vertaling copyright ASPNL)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL