Delen via


Een DataAdapter gebruiken om een DataSet te vullen

Het ADO.NET DataSet is een geheugen-residente weergave van gegevens die een consistent relationeel programmeermodel biedt, onafhankelijk van de gegevensbron. De DataSet tabel vertegenwoordigt een volledige set gegevens met tabellen, beperkingen en relaties tussen de tabellen. Omdat de DataSet onafhankelijk is van de gegevensbron, kan een DataSet zowel gegevens bevatten die lokaal zijn voor de toepassing als gegevens uit meerdere gegevensbronnen. Interactie met bestaande gegevensbronnen wordt beheerd via de DataAdapter.

De SelectCommand eigenschap van het DataAdapter object is een Command object waarmee gegevens uit de gegevensbron worden opgehaald. De InsertCommand, UpdateCommanden DeleteCommand eigenschappen van de DataAdapter objecten zijn Command objecten die updates voor de gegevens in de gegevensbron beheren op basis van wijzigingen in de gegevens in de DataSet. Deze eigenschappen worden uitgebreider besproken in het bijwerken van gegevensbronnen met DataAdapters.

De Fill methode van de DataAdapter wordt gebruikt om een DataSet te vullen met de resultaten van de SelectCommand van de DataAdapter. Fill gebruikt als argumenten een DataSet die moet worden ingevuld en een DataTable-object, of de naam van de DataTable die gevuld moet worden met de rijen die worden geretourneerd door de SelectCommand.

Opmerking

DataAdapter Het ophalen van alle tabellen kost tijd, met name als er veel rijen in de tabel staan. Dit komt doordat het verkrijgen van toegang tot de database, het zoeken en verwerken van de gegevens en het overdragen van de gegevens naar de client tijdrovend is. Als u alle tabellen naar de client haalt, worden ook alle rijen op de server vergrendeld. Om de prestaties te verbeteren, kunt u de WHERE component gebruiken om het aantal rijen dat naar de client wordt geretourneerd aanzienlijk te verminderen. U kunt ook de hoeveelheid gegevens die naar de client worden geretourneerd verminderen door alleen expliciet vereiste kolommen in de SELECT instructie weer te geven. Een andere goede tijdelijke oplossing is om de rijen in batches (zoals enkele honderden rijen tegelijk) op te halen en alleen de volgende batch op te halen wanneer de client klaar is met de huidige batch.

De Fill methode gebruikt het DataReader object impliciet om de kolomnamen en -typen te retourneren die worden gebruikt om de tabellen in de DataSettabel te maken en de gegevens om de rijen van de tabellen in de DataSettabel te vullen. Tabellen en kolommen worden alleen gemaakt als ze nog niet bestaan; anders Fill wordt het bestaande DataSet schema gebruikt. Kolomtypen worden gemaakt als .NET Framework-typen op basis van de tabellen in gegevenstypetoewijzingen in ADO.NET. Primaire sleutels worden niet gemaakt, tenzij deze in de gegevensbron aanwezig zijn en DataAdapter.MissingSchemaAction is ingesteld op MissingSchemaAction.AddWithKey. Als Fill wordt gevonden dat er een primaire sleutel bestaat voor een tabel, worden gegevens in de DataSet tabel overschreven met gegevens uit de gegevensbron voor rijen waarin de waarden van de primaire sleutelkolom overeenkomen met die van de rij die is geretourneerd uit de gegevensbron. Als er geen primaire sleutel wordt gevonden, worden de gegevens toegevoegd aan de tabel in DataSet. Fill maakt gebruik van eventuele bestaande toewijzingen wanneer u de DataSet vult (zie DataAdapter DataTable en DataColumn Mappings).

Opmerking

Als de SelectCommand de resultaten van een OUTER JOIN retourneert, stelt de DataAdapter geen PrimaryKey-waarde in voor het resulterende DataTable. U moet de PrimaryKey zelf definiëren om ervoor te zorgen dat dubbele rijen correct worden opgelost. Zie Primaire sleutels definiëren voor meer informatie.

In het volgende codevoorbeeld wordt een exemplaar van een SqlDataAdapter gemaakt dat gebruikmaakt van een SqlConnection om verbinding te maken met de Microsoft SQL Server Northwind-database en een DataTable vult in een DataSet met de lijst van klanten. De SQL-instructie en SqlConnection-argumenten die aan de SqlDataAdapter constructor zijn doorgegeven, worden gebruikt om de eigenschap SelectCommand van de SqlDataAdapter te creëren.

Voorbeeld

' Assumes that connection is a valid SqlConnection object.  
Dim queryString As String = _  
  "SELECT CustomerID, CompanyName FROM dbo.Customers"  
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _  
  queryString, connection)  
  
Dim customers As DataSet = New DataSet  
adapter.Fill(customers, "Customers")  
// Assumes that connection is a valid SqlConnection object.  
string queryString =
  "SELECT CustomerID, CompanyName FROM dbo.Customers";  
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);  
  
DataSet customers = new DataSet();  
adapter.Fill(customers, "Customers");  

Opmerking

De code die in dit voorbeeld wordt weergegeven, laat niet expliciet zien hoe Connection geopend en gesloten moet worden. De Fill-methode opent impliciet de Connection die de DataAdapter gebruikt, als wordt vastgesteld dat de verbinding nog niet open is. Als Fill de verbinding is geopend, wordt de verbinding ook gesloten wanneer Fill de verbinding is voltooid. Dit kan je code vereenvoudigen als je één bewerking, zoals een Fill of een Update, uitvoert. Als u echter meerdere bewerkingen uitvoert waarvoor een open verbinding is vereist, kunt u de prestaties van uw toepassing verbeteren door expliciet de methode van de OpenConnectiontoepassing aan te roepen, de bewerkingen uit te voeren op basis van de gegevensbron en vervolgens de Close methode van de Connectiontoepassing aan te roepen. Probeer verbindingen met de gegevensbron zo kort mogelijk open te houden om gratis resources te gebruiken voor gebruik door andere clienttoepassingen.

Meerdere resultatensets

Als DataAdapter meerdere resultatensets tegenkomt, worden er meerdere tabellen in DataSet gemaakt. De tabellen krijgen een incrementele standaardnaam van TabelN, te beginnen met 'Tabel' voor Table0. Als een tabelnaam wordt doorgegeven als argument voor de Fill methode, krijgen de tabellen een incrementele standaardnaam van TableNameN, te beginnen met TableName0.

Een DataSet invullen met gegevens van meerdere DataAdapters

Een willekeurig aantal DataAdapter objecten kan worden gebruikt met een DataSet. Elk DataAdapter object kan worden gebruikt om een of meer DataTable objecten te vullen en updates terug te sturen naar de relevante gegevensbron. DataRelation en Constraint objecten kunnen lokaal worden toegevoegd DataSet , zodat u gegevens uit verschillende gegevensbronnen kunt relateren. Een DataSet database kan bijvoorbeeld gegevens bevatten uit een Microsoft SQL Server-database, een IBM DB2-database die wordt weergegeven via OLE DB en een gegevensbron die XML streamt. Een of meer DataAdapter objecten kunnen communicatie met elke gegevensbron verwerken.

Voorbeeld

In het volgende codevoorbeeld wordt een lijst gevuld met klanten uit de Northwind database op Microsoft SQL Server en een lijst met orders uit de Northwind database die is opgeslagen in Microsoft Access 2000. De gevulde tabellen zijn verbonden met een DataRelation, en vervolgens wordt de klantenlijst weergegeven samen met de bijbehorende orders van die klant. Zie DataRelation en Navigeren in DataRelations voor meer informatie over objecten.

' Assumes that customerConnection is a valid SqlConnection object.  
' Assumes that orderConnection is a valid OleDbConnection object.  
Dim custAdapter As SqlDataAdapter = New SqlDataAdapter( _  
  "SELECT * FROM dbo.Customers", customerConnection)  
  
Dim ordAdapter As OleDbDataAdapter = New OleDbDataAdapter( _  
  "SELECT * FROM Orders", orderConnection)  
  
Dim customerOrders As DataSet = New DataSet()  
custAdapter.Fill(customerOrders, "Customers")  
ordAdapter.Fill(customerOrders, "Orders")  
  
Dim relation As DataRelation = _  
  customerOrders.Relations.Add("CustOrders", _  
  customerOrders.Tables("Customers").Columns("CustomerID"), _
  customerOrders.Tables("Orders").Columns("CustomerID"))  
  
Dim pRow, cRow As DataRow  
For Each pRow In customerOrders.Tables("Customers").Rows  
  Console.WriteLine(pRow("CustomerID").ToString())  
  
  For Each cRow In pRow.GetChildRows(relation)  
    Console.WriteLine(vbTab & cRow("OrderID").ToString())  
  Next  
Next  
// Assumes that customerConnection is a valid SqlConnection object.  
// Assumes that orderConnection is a valid OleDbConnection object.  
SqlDataAdapter custAdapter = new SqlDataAdapter(  
  "SELECT * FROM dbo.Customers", customerConnection);  
OleDbDataAdapter ordAdapter = new OleDbDataAdapter(  
  "SELECT * FROM Orders", orderConnection);  
  
DataSet customerOrders = new DataSet();  
  
custAdapter.Fill(customerOrders, "Customers");  
ordAdapter.Fill(customerOrders, "Orders");  
  
DataRelation relation = customerOrders.Relations.Add("CustOrders",  
  customerOrders.Tables["Customers"].Columns["CustomerID"],  
  customerOrders.Tables["Orders"].Columns["CustomerID"]);  
  
foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)  
{  
  Console.WriteLine(pRow["CustomerID"]);  
   foreach (DataRow cRow in pRow.GetChildRows(relation))  
    Console.WriteLine("\t" + cRow["OrderID"]);  
}  

Decimaal type SQL Server

Standaard worden gegevens DataSet opgeslagen met behulp van .NET Framework-gegevenstypen. Voor de meeste toepassingen bieden deze een handige weergave van gegevensbroninformatie. Deze weergave kan echter een probleem veroorzaken wanneer het gegevenstype in de gegevensbron een decimaal of numeriek gegevenstype van SQL Server is. Het .NET Framework-gegevenstype decimal staat maximaal 28 significante cijfers toe, terwijl het SQL Server-gegevenstype decimal 38 significante cijfers toestaat. Als de SqlDataAdapter bepaalt tijdens een Fill bewerking dat de precisie van een SQL Server-veld decimal groter is dan 28 tekens, wordt de huidige rij niet toegevoegd aan de DataTable. In plaats daarvan treedt de FillError gebeurtenis op, waarmee u kunt bepalen of een verlies van precisie plaatsvindt en op de juiste manier reageert. Zie FillError voor meer informatie over de gebeurtenis. Als u de SQL Server-waarde decimal wilt ophalen, kunt u ook een SqlDataReader object gebruiken en de GetSqlDecimal methode aanroepen.

ADO.NET 2.0 introduceerde verbeterde ondersteuning voor System.Data.SqlTypes in de DataSet. Zie SqlTypes en de DataSet voor meer informatie.

OLE DB-hoofdstukken

Hiërarchische rijensets of hoofdstukken (OLE DB-type DBTYPE_HCHAPTER, ADO-type adChapter) kunnen worden gebruikt om de inhoud van een DataSet. Wanneer OleDbDataAdapter een hoofdstukkolom tegenkomt tijdens een Fill bewerking, wordt er een DataTable gemaakt voor de hoofdstukkolom en wordt die tabel gevuld met de kolommen en rijen uit het hoofdstuk. De tabel die voor de hoofdstukkolom is gemaakt, krijgt een naam met zowel de naam van de bovenliggende tabel als de naam van de hoofdstukkolom in het formulier ParentTableNameChapteredColumnName. Als er al een tabel bestaat die DataSet overeenkomt met de naam van de hoofdstukkolom, wordt de huidige tabel gevuld met de hoofdstukgegevens. Als er geen kolom in een bestaande tabel is die overeenkomt met een kolom in het hoofdstuk, wordt er een nieuwe kolom toegevoegd.

Voordat de tabellen in de DataSet zijn gevuld met de gegevens uit de kolommen van het hoofdstuk, wordt er een relatie gemaakt tussen de ouder- en kindtabellen van de hiërarchische rijenset door een integerkolom toe te voegen aan zowel de ouder- als de kindtabel. De kolom in de oudertabel wordt ingesteld op automatisch toenemen en er wordt een DataRelation relatie gemaakt met behulp van de toegevoegde kolommen uit beide tabellen. De toegevoegde relatie wordt benoemd met behulp van de bovenliggende tabel- en hoofdstukkolomnamen in de vorm 'ParentTableNameChapterColumnName'.

Houd er rekening mee dat de gerelateerde kolom alleen bestaat in de DataSet. Volgende opvullingen uit de gegevensbron kunnen ertoe leiden dat nieuwe rijen aan de tabellen worden toegevoegd in plaats van dat wijzigingen worden samengevoegd in bestaande rijen.

Houd er ook rekening mee dat als u de DataAdapter.Fill overload gebruikt die een DataTable gebruikt, alleen die tabel wordt gevuld. Er wordt nog steeds een kolom met automatisch oplopende gehele getallen aan de tabel toegevoegd, maar er wordt geen kindtabel aangemaakt of gevuld en er wordt geen relatie gemaakt.

In het volgende voorbeeld wordt de MSDataShape-provider gebruikt om een hoofdstukkolom met orders te genereren voor elke klant in een lijst met klanten. A DataSet wordt vervolgens gevuld met de gegevens.

Using connection As OleDbConnection = New OleDbConnection( _  
  "Provider=MSDataShape;Data Provider=SQLOLEDB;" & _  
  "Data Source=(local);Integrated " & _  
  "Security=SSPI;Initial Catalog=northwind")  
  
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter( _  
  "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " & _  
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " & _  
  "RELATE CustomerID TO CustomerID)", connection)  
  
Dim customers As DataSet = New DataSet()  
  
adapter.Fill(customers, "Customers")  
End Using  
using (OleDbConnection connection = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +  
  "Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind"))  
{  
OleDbDataAdapter adapter = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +  
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +  
  "RELATE CustomerID TO CustomerID)", connection);  
  
DataSet customers = new DataSet();  
adapter.Fill(customers, "Customers");  
}  

Wanneer de Fill bewerking is voltooid, bevat de DataSet twee tabellen: Customers en CustomersOrders, waarbij CustomersOrders de kolom met hoofdstukken voorstelt. Er wordt een extra kolom met de naam Orders toegevoegd aan de Customers tabel en er wordt een extra kolom met de naam CustomersOrders toegevoegd aan de CustomersOrders tabel. De Orders kolom in de Customers tabel is ingesteld op automatisch verhogen. Een DataRelation, CustomersOrders, wordt gemaakt met behulp van de kolommen die zijn toegevoegd aan de tabellen met Customers als de oudertabel. In de volgende tabellen ziet u enkele voorbeeldresultaten.

Tabelnaam: Klanten

KlantID Bedrijfsnaam Bestellingen
ALFKI Alfreds Futterkiste 0
ANATR Ana Analytics Emparedados y helados 1

TableName: KlantenBestellingen

KlantID Order-id KlantenBestellingen
ALFKI 10643 0
ALFKI 10692 0
ANATR 10308 1
ANATR 10625 1

Zie ook