Auffüllen eines Datasets aus einem DataAdapter
Gilt für: .NET Framework .NET .NET Standard
Das ADO.NET-DataSet ist eine speicherresidente Datendarstellung, das ein konsistentes relationales und von der Datenquelle unabhängiges Programmiermodell bereitstellt. Das DataSet
stellt eine vollständige Datengruppe einschließlich Tabellen, Einschränkungen und Beziehungen zwischen Tabellen dar. Da das DataSet
von der Datenquelle unabhängig ist, kann ein DataSet
sowohl lokale Daten einer Anwendung als auch Daten aus mehreren Datenquellen enthalten. Die Interaktion mit vorhandenen Datenquellen wird über den DataAdapter
gesteuert.
Die SelectCommand
-Eigenschaft des DataAdapter
ist ein Command
-Objekt, das Daten aus der Datenquelle abruft. Die InsertCommand
-Eigenschaft, die UpdateCommand
-Eigenschaft und die DeleteCommand
-Eigenschaft des DataAdapter
sind Command
-Objekte, die Updates an den Daten in der Datenquelle entsprechend den Modifikationen an den Daten im DataSet
verwalten. Diese Eigenschaften werden unter Aktualisieren von Datenquellen mit DataAdapter-Klassen ausführlicher behandelt.
Mithilfe der Fill
-Methode des DataAdapter
wird ein DataSet
mit den Ergebnissen vom SelectCommand
des DataAdapter
aufgefüllt. Fill
verwendet als Argumente ein aufzufüllendes DataSet
sowie ein DataTable
-Objekt bzw. den Namen der DataTable
, die mit den Zeilen gefüllt werden soll, die vom SelectCommand
zurückgegeben werden.
Hinweis
Die Verwendung des DataAdapter
zum Abrufen einer gesamten Tabelle kann einige Zeit in Anspruch nehmen, insbesondere, wenn die Tabelle viele Zeilen enthält. Der Grund hierfür ist, dass das Zugreifen auf die Datenbank und das Auffinden, Verarbeiten und Übertragen der Daten an den Client zeitaufwändig ist. Durch das Abrufen der gesamten Tabelle seitens des Clients werden außerdem alle ihre Zeilen auf dem Server gesperrt. Zur Verbesserung der Leistung können Sie die WHERE
-Klausel verwenden, um die Anzahl der an den Client zurückgegebenen Zeilen deutlich zu reduzieren. Die Anzahl der an den Client zurückgegebenen Daten kann auch verringert werden, indem Sie in der SELECT
-Anweisung nur die erforderlichen Spalten explizit auflisten. Eine weitere gute Möglichkeit, dieses Problem zu umgehen, besteht darin, die Zeilen in Stapeln (z. B. immer einige hundert Zeilen auf einmal) abzurufen, wobei der nächste Stapel erst dann abgerufen wird, wenn der Client mit dem aktuellen Stapel fertig ist.
Die Fill
-Methode verwendet das DataReader
-Objekt implizit, um die Spaltennamen und Spaltentypen zurückzugeben, mit denen die Tabellen im DataSet
erstellt werden, sowie die Daten zum Füllen der Tabellenzeilen im DataSet
. Tabellen und Spalten werden nur erstellt, wenn sie noch nicht vorhanden sind. Andernfalls verwendet die Fill
-Methode das vorhandene DataSet
-Schema. Spaltentypen werden als .NET Framework-Typen gemäß den Tabellen unter Datentypzuordnungen in ADO.NET erstellt. Primärschlüssel werden nur erstellt, wenn diese in der Datenquelle vorhanden sind und DataAdapter
.MissingSchemaAction
auf MissingSchemaAction
.AddWithKey
festgelegt ist. Wenn die Fill
-Methode ermittelt, dass ein Primärschlüssel für eine Tabelle vorhanden ist, werden Daten im DataSet
mit den Daten aus der Datenquelle überschrieben. Dies gilt für Zeilen, deren Werte in der Primärschlüsselspalte mit denen der Zeile übereinstimmen, die von der Datenquelle zurückgegeben wurde. Wurde kein Primärschlüssel gefunden, so werden die Daten an die Tabellen im DataSet
angehängt. Fill
verwendet alle Zuordnungen, die möglicherweise vorhanden sind, wenn Sie die DataSet
-Klasse auffüllen (siehe DataAdapter-, DataTable- und DataColumn-Zuordnungen).
Hinweis
Wenn vom SelectCommand
die Ergebnisse eines OUTER JOIN zurückgegeben werden, wird vom DataAdapter
kein PrimaryKey
-Wert für die resultierende DataTable
festgelegt. Sie müssen den PrimaryKey
selbst definieren, um sicherzustellen, dass doppelte Zeilen ordnungsgemäß aufgelöst werden.
Im folgenden Codebeispiel wird eine Instanz eines SqlDataAdapter erstellt, die eine SqlConnection zur Microsoft SQL Server-Datenbank Northwind
verwendet und eine DataTable in einem DataSet
mit der Kundenliste füllt. Mit der SQL-Anweisung und den SqlConnection -Argumenten, die an den SqlDataAdapter -Konstruktor übergeben werden, wird die SelectCommand -Eigenschaft des SqlDataAdaptererstellt.
Beispiel
// 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");
Hinweis
Der in diesem Beispiel dargestellte Code öffnet und schließt die Connection
nicht explizit. Die Fill
-Methode öffnet implizit die Connection
, die vom DataAdapter
verwendet wird, wenn die Verbindung nicht bereits geöffnet ist. Wenn die Verbindung durch Fill
geöffnet wurde, wird sie nach dem Fill
-Vorgang auch wieder geschlossen. Bei einzelnen Vorgängen wie Fill
oder Update
kann der Code auf diese Weise vereinfacht werden. Wenn Sie jedoch mehrere Vorgänge durchführen, für die eine geöffnete Verbindung erforderlich ist, können Sie die Leistung der Anwendung verbessern, indem Sie explizit die Open
-Methode der Connection
aufrufen, die Vorgänge für die Datenquelle durchführen und anschließend die Close
-Methode der Connection
aufrufen. Sie sollten die Verbindungen zur Datenquelle so kurz wie möglich geöffnet lassen, um die Ressourcen freizugeben, die von anderen Clientanwendungen verwendet werden.
Mehrere Resultsets
Wenn der DataAdapter
mehrere Resultsets ermittelt, werden mehrere Tabellen im DataSet
erstellt. Diesen Tabellen werden standardmäßig Namen nach dem Schema TableN, beginnend mit "Table" für Table0, zugewiesen, die jeweils um eins erhöht werden. Wenn der Tabellenname als Argument an die Fill
-Methode übergeben wird, erhalten die Tabellen standardmäßig Namen nach dem Schema TableNameN, beginnend mit "TableName" für TableName0, die jeweils um eins erhöht werden.
Auffüllen einer DataSet-Klasse aus mehreren DataAdapter-Klassen
Eine DataSet
-Klasse kann mit einer beliebigen Anzahl von DataAdapter
-Objekten verwendet werden. Mit jedem DataAdapter
-Objekt können ein oder mehrere DataTable
-Objekte gefüllt und Updates in die zugehörige Datenquelle übernommen werden. DasDataRelation
-Objekt und das Constraint
-Objekt können dem DataSet
lokal hinzugefügt werden. Dadurch haben Sie die Möglichkeit, Daten aus mehreren unähnlichen Datenquellen zu verbinden. Ein DataSet
kann beispielsweise Daten aus einer Microsoft SQL Server-Datenbank, einer über OLE DB verfügbar gemachten IBM Db2-Datenbank und einer XML-Datenquelle enthalten. Für die Kommunikation mit den einzelnen Datenquellen sind ein oder mehrere DataAdapter
-Objekte zuständig.
Beispiel
Im folgenden Codebeispiel wird eine Kundenliste von der Northwind
-Datenbank unter Microsoft SQL Server sowie eine Auftragsliste von der in Microsoft Access gespeicherten Northwind
-Datenbank gefüllt. Die gefüllten Tabellen werden mit einer DataRelation
verbunden, und die Kundenliste wird anschließend mit Aufträgen für den jeweiligen Kunden angezeigt.
// Assumes that customerConnection and orderConnection are valid SqlConnection objects.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", customerConnection);
SqlDataAdapter ordAdapter = new SqlDataAdapter(
"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"]);
}
SQL Server-Typ decimal
Standardmäßig speichert die DataSet
-Klasse Daten mithilfe von .NET-Datentypen. Für die meisten Anwendungen sind diese sehr gut zur Darstellung der Informationen aus der Datenquelle geeignet. Diese Darstellung kann jedoch problematisch werden, wenn es sich bei dem Datentyp in der Datenquelle um den SQL Server-Datentyp „decimal“ oder um einen numerischen Datentyp handelt. Der .NET-Datentyp decimal
lässt maximal 28 signifikante Stellen zu, während der SQL Server-Datentyp decimal
38 signifikante Stellen zulässt. Wenn der SqlDataAdapter
während eines Fill
-Vorgangs feststellt, dass die Präzision eines SQL Server-Felds mit dem Datentyp decimal
mehr als 28 Zeichen beträgt, wird der DataTable
die aktuelle Zeile nicht hinzugefügt. Stattdessen tritt das FillError
-Ereignis auf. Dadurch können Sie überprüfen, ob ein Präzisionsverlust eintritt, und Sie können entsprechend reagieren. Weitere Informationen zum FillError
-Ereignis finden Sie unter Umgang mit DataAdapter-Ereignissen. Den SQL Server-Wert decimal
erhalten Sie auch, indem Sie ein SqlDataReader -Objekt verwenden und die GetSqlDecimal -Methode aufrufen.
ADO.NET enthält auch erweiterte Unterstützung für System.Data.SqlTypes in der DataSet
-Klasse. Weitere Informationen finden Sie unter SqlTypes and the DataSet.