Een DataSet uit een DataAdapter 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
gegevensbron onafhankelijk is van de gegevensbron, kan dit DataSet
gegevens bevatten die lokaal zijn voor de toepassing en 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
, UpdateCommand
en 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
methode wordt gebruikt om een DataSet
met de resultaten van de SelectCommand
DataAdapter
. Fill
gebruikt als argumenten die moeten DataSet
worden ingevuld en een DataTable
object, of de naam van de DataTable
te vullen rijen van de SelectCommand
.
Notitie
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 DataSet
tabel te maken en de gegevens om de rijen van de tabellen in de DataSet
tabel 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 tabellen in de DataSet
tabel. Fill
maakt gebruik van toewijzingen die kunnen bestaan wanneer u de DataSet
toewijzingen (zie DataAdapter DataTable en DataColumn-toewijzingen) vult.
Notitie
Als de SelectCommand
resultaten van een OUTER JOIN worden geretourneerd, DataAdapter
wordt er geen waarde ingesteld PrimaryKey
voor het resulterende DataTable
. U moet de PrimaryKey
uzelf definiëren om ervoor te zorgen dat dubbele rijen correct zijn opgelost. Zie Primaire sleutels definiëren voor meer informatie.
In het volgende codevoorbeeld wordt een exemplaar gemaakt van een SqlDataAdapter exemplaar dat gebruikmaakt van een SqlConnection database van Microsoft SQL Server Northwind
en een DataTable exemplaar vult in een DataSet
met de lijst met klanten. De SQL-instructie en SqlConnection -argumenten die aan de SqlDataAdapter constructor worden doorgegeven, worden gebruikt om de SelectCommand eigenschap van de SqlDataAdapter.
Opmerking
' 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");
Notitie
De code die in dit voorbeeld wordt weergegeven, wordt niet expliciet geopend en gesloten Connection
. De Fill
methode opent impliciet het gebruik van de DataAdapter
Connection
methode als wordt gevonden dat de verbinding nog niet is geopend. Als Fill
de verbinding is geopend, wordt de verbinding ook gesloten wanneer Fill
de verbinding is voltooid. Dit kan uw code vereenvoudigen wanneer u één bewerking zoals een Fill
of een Update
. 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 Open
Connection
toepassing aan te roepen, de bewerkingen uit te voeren op basis van de gegevensbron en vervolgens de Close
methode van de Connection
toepassing 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 er DataAdapter
meerdere resultatensets optreden, worden er meerdere tabellen in de DataSet
tabel 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 uit meerdere DataAdapters invullen
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.
Opmerking
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 gerelateerd aan een DataRelation
en de lijst met klanten wordt vervolgens weergegeven met de orders voor die klant. Zie DataRelations toevoegen en Navigeren in DataRelations voor meer informatie over DataRelation
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 DataAdapter-gebeurtenissen verwerken voor meer informatie over de FillError
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 heeft in System.Data.SqlTypes 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 tijdens OleDbDataAdapter een Fill
bewerking een hoofdstukkolom wordt aangeroepen, 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
tabellen worden gevuld met de gegevens in de hoofdstukkolommen, wordt er een relatie gemaakt tussen de bovenliggende en onderliggende tabellen van de hiërarchische rijenset door een kolom met gehele getallen toe te voegen aan zowel de bovenliggende als de onderliggende tabel, de bovenliggende kolom in te stellen op automatisch verhogen en een DataRelation
relatie te maken 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
overbelasting gebruikt die een DataTable
, alleen die tabel wordt gevuld. Er wordt nog steeds een kolom met automatisch verhogende gehele getallen toegevoegd aan de tabel, maar er wordt geen onderliggende tabel gemaakt 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 hoofdstukkolom wordt aangegeven. 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. A DataRelation
, CustomersOrders
wordt gemaakt met behulp van de kolommen die zijn toegevoegd aan de tabellen met Customers
als de bovenliggende tabel. In de volgende tabellen ziet u enkele voorbeeldresultaten.
TableName: Klanten
CustomerID | CompanyName | Orders |
---|---|---|
ALFKI | Alfreds Futterkiste | 0 |
ANATR | Ana Analytics Emparedados y helados | 1 |
TableName: CustomersOrders
CustomerID | OrderID | KlantenOrders |
---|---|---|
ALFKI | 10643 | 0 |
ALFKI | 10692 | 0 |
ANATR | 10308 | 1 |
ANATR | 10625 | 1 |