Wypełnianie zestawu danych z elementu DataAdapter
ADO.NET DataSet to reprezentacja danych rezydenta pamięci, która zapewnia spójny model programowania relacyjnego niezależnie od źródła danych. Reprezentuje DataSet
kompletny zestaw danych, który zawiera tabele, ograniczenia i relacje między tabelami. DataSet
Ponieważ obiekt jest niezależny od źródła danych, DataSet
obiekt może zawierać dane lokalne w aplikacji i dane z wielu źródeł danych. Interakcja z istniejącymi źródłami danych jest kontrolowana za pośrednictwem elementu DataAdapter
.
Właściwość SelectCommand
DataAdapter
obiektu to Command
obiekt, który pobiera dane ze źródła danych. Właściwości InsertCommand
DataAdapter
, UpdateCommand
i DeleteCommand
to Command
obiekty, które zarządzają aktualizacjami danych w źródle danych zgodnie z modyfikacjami wprowadzonych w danych w obiekcie DataSet
. Te właściwości zostały szczegółowo omówione w temacie Aktualizowanie źródeł danych za pomocą elementów DataAdapters.
Metoda Fill
DataAdapter
metody jest używana do wypełniania obiektu DataSet
wynikami SelectCommand
obiektu DataAdapter
. Fill
przyjmuje jako argumenty DataSet
, które mają zostać wypełnione, oraz DataTable
obiekt lub nazwę DataTable
obiektu, który ma zostać wypełniony wierszami zwróconymi z obiektu SelectCommand
.
Uwaga
DataAdapter
Pobieranie całej tabeli wymaga czasu, zwłaszcza jeśli w tabeli znajduje się wiele wierszy. Dzieje się tak, ponieważ uzyskiwanie dostępu do bazy danych, lokalizowanie i przetwarzanie danych, a następnie przesyłanie danych do klienta jest czasochłonne. Ściąganie całej tabeli do klienta powoduje również zablokowanie wszystkich wierszy na serwerze. Aby zwiększyć wydajność, możesz użyć WHERE
klauzuli , aby znacznie zmniejszyć liczbę wierszy zwracanych do klienta. Możesz również zmniejszyć ilość danych zwracanych do klienta, jawnie wyświetlając tylko wymagane kolumny w instrukcji SELECT
. Innym dobrym obejściem jest pobranie wierszy w partiach (takich jak kilkaset wierszy naraz) i pobranie następnej partii tylko po zakończeniu pracy klienta z bieżącą partią.
Metoda Fill
używa DataReader
obiektu niejawnie do zwracania nazw kolumn i typów, które są używane do tworzenia tabel w DataSet
obiekcie , oraz danych w celu wypełnienia wierszy tabel w tabeli DataSet
. Tabele i kolumny są tworzone tylko wtedy, gdy jeszcze nie istnieją; w przeciwnym razie Fill
używa istniejącego DataSet
schematu. Typy kolumn są tworzone jako typy programu .NET Framework zgodnie z tabelami w mapowaniach typów danych w ADO.NET. Klucze podstawowe nie są tworzone, chyba że istnieją w źródle danych i DataAdapter
ustawiono wartość .MissingSchemaAction
MissingSchemaAction
AddWithKey
Jeśli Fill
okaże się, że dla tabeli istnieje klucz podstawowy, zastąpi on dane z DataSet
danych ze źródła danych dla wierszy, w których wartości kolumny klucza podstawowego są zgodne z wartościami wiersza zwróconego ze źródła danych. Jeśli nie znaleziono klucza podstawowego, dane są dołączane do tabel w pliku DataSet
. Fill
używa mapowań, które mogą istnieć po wypełnieniu DataSet
elementu (zobacz DataAdapter DataTable i DataColumn Mappings).
Uwaga
SelectCommand
Jeśli funkcja zwraca wyniki sprzężenia ZEWNĘTRZNEgo, DataAdapter
parametr nie ustawia PrimaryKey
wartości wynikowej DataTable
. Należy zdefiniować PrimaryKey
samodzielnie, aby upewnić się, że zduplikowane wiersze są poprawnie rozpoznawane. Aby uzyskać więcej informacji, zobacz Definiowanie kluczy podstawowych.
Poniższy przykład kodu tworzy wystąpienie obiektu SqlDataAdapter , które używa SqlConnection obiektu do bazy danych programu Microsoft SQL Server Northwind
i wypełnia obiekt DataTable na DataSet
liście klientów. Instrukcja SQL i SqlConnection argumenty przekazane do konstruktora SqlDataAdapter są używane do tworzenia SelectCommand właściwości SqlDataAdapter.
Przykład
' 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");
Uwaga
Kod pokazany w tym przykładzie nie otwiera jawnie i nie zamyka pliku Connection
. Metoda Fill
niejawnie otwiera metodę Connection
, która DataAdapter
jest używana, jeśli okaże się, że połączenie nie jest jeszcze otwarte. Jeśli Fill
połączenie zostało otwarte, zamyka również połączenie po Fill
zakończeniu. Może to uprościć kod, gdy zajmujesz się pojedynczą operacjąUpdate
, taką jak lub Fill
. Jeśli jednak wykonujesz wiele operacji wymagających otwartego połączenia, możesz zwiększyć wydajność aplikacji, jawnie wywołując Open
metodę Connection
, wykonując operacje względem źródła danych, a następnie wywołując Close
metodę .Connection
Należy starać się zachować otwarte połączenia ze źródłem danych tak krótko, jak to możliwe, aby zwolnić zasoby do użytku przez inne aplikacje klienckie.
Wiele zestawów wyników
DataAdapter
Jeśli napotka wiele zestawów wyników, tworzy wiele tabel w obiekcie DataSet
. Tabele otrzymują przyrostową nazwę domyślną tabeliN, zaczynając od "Tabela" dla tabeli Table0. Jeśli nazwa tabeli jest przekazywana jako argument do Fill
metody, tabele otrzymują przyrostową domyślną nazwę TableNameN, zaczynając od "TableName" dla tableName0.
Wypełnianie zestawu danych z wielu elementów DataAdapters
Dowolna DataAdapter
liczba obiektów może być używana z elementem DataSet
. Każdy DataAdapter
może służyć do wypełniania co najmniej jednego DataTable
obiektu i rozwiązywania aktualizacji z powrotem do odpowiedniego źródła danych. DataRelation
obiekty i Constraint
można dodawać do środowiska lokalnego DataSet
, co umożliwia powiązanie danych z innych źródeł danych. Na przykład obiekt DataSet
może zawierać dane z bazy danych programu Microsoft SQL Server, bazy danych IBM DB2 uwidocznionej za pośrednictwem OLE DB oraz źródła danych, które przesyła strumieniowo kod XML. DataAdapter
Co najmniej jeden obiekt może obsługiwać komunikację z poszczególnymi źródłami danych.
Przykład
Poniższy przykład kodu wypełnia listę klientów z Northwind
bazy danych programu Microsoft SQL Server oraz listę zamówień z bazy danych przechowywanej Northwind
w programie Microsoft Access 2000. Wypełnione tabele są powiązane z tabelą DataRelation
, a lista klientów jest następnie wyświetlana z zamówieniami dla tego klienta. Aby uzyskać więcej informacji na temat DataRelation
obiektów, zobacz Dodawanie obiektów DataRelations i Nawigowanie po elementach DataRelations.
' 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"]);
}
Typ dziesiętny programu SQL Server
Domyślnie dane DataSet
są przechowywane przy użyciu typów danych programu .NET Framework. W przypadku większości aplikacji zapewniają one wygodną reprezentację informacji o źródle danych. Jednak ta reprezentacja może spowodować problem, gdy typ danych w źródle danych jest typem danych dziesiętnym lub liczbowym programu SQL Server. Typ danych programu .NET Framework decimal
umożliwia maksymalnie 28 cyfr znaczących, natomiast typ danych programu SQL Server decimal
umożliwia użycie 38 cyfr znaczących. SqlDataAdapter
Jeśli parametr określa podczas Fill
operacji, że precyzja pola programu SQL Server decimal
jest większa niż 28 znaków, bieżący wiersz nie jest dodawany do obiektu DataTable
. FillError
Zamiast tego występuje zdarzenie, co pozwala określić, czy wystąpi utrata precyzji i odpowiednio zareagować. Aby uzyskać więcej informacji na temat FillError
zdarzenia, zobacz Obsługa zdarzeń dataadapter. Aby uzyskać wartość programu SQL Server decimal
, możesz również użyć SqlDataReader obiektu i wywołać metodę GetSqlDecimal .
ADO.NET 2.0 wprowadzono rozszerzoną obsługę System.Data.SqlTypes w systemie DataSet
. Aby uzyskać więcej informacji, zobacz SqlTypes i DataSet.
Rozdziały OLE DB
Hierarchiczne zestawy wierszy lub rozdziały (typ DBTYPE_HCHAPTER
OLE DB , typ adChapter
ADO ) mogą służyć do wypełniania zawartości elementu DataSet
. Gdy OleDbDataAdapter podczas operacji napotkana jest kolumna Fill
rozdziału, element DataTable
jest tworzony dla kolumny z rozdziałem, a ta tabela jest wypełniona kolumnami i wierszami z rozdziału. Tabela utworzona dla kolumny rozdziału ma nazwę przy użyciu zarówno nazwy tabeli nadrzędnej, jak i nazwy kolumny rozdziału w formularzu "ParentTableNameChapteredColumnName". Jeśli tabela już istnieje w tabeli DataSet
zgodnej z nazwą kolumny rozdziału, bieżąca tabela jest wypełniona danymi rozdziału. Jeśli w istniejącej tabeli nie ma kolumny zgodnej z kolumną znajdującą się w rozdziale, zostanie dodana nowa kolumna.
Zanim tabele w tabeli DataSet
zostaną wypełnione danymi w kolumnach rozdziałów, zostanie utworzona relacja między tabelami nadrzędnymi i podrzędnymi zestawu wierszy hierarchicznych przez dodanie kolumny całkowitej do tabeli nadrzędnej i podrzędnej, ustawienie kolumny nadrzędnej na automatyczne zwiększanie i utworzenie DataRelation
przy użyciu dodanych kolumn z obu tabel. Dodawana relacja ma nazwę przy użyciu nazwy kolumn tabeli nadrzędnej i rozdziału w postaci "ParentTableNameChapterColumnName".
Należy pamiętać, że powiązana kolumna istnieje tylko w obiekcie DataSet
. Kolejne wypełnienia ze źródła danych mogą spowodować dodanie nowych wierszy do tabel zamiast scalania zmian w istniejących wierszach.
Należy również pamiętać, że jeśli używasz DataAdapter.Fill
przeciążenia, które przyjmuje DataTable
wartość , tylko ta tabela zostanie wypełniona. Kolumna automatycznego zwiększania liczby całkowitej będzie nadal dodawana do tabeli, ale żadna tabela podrzędna nie zostanie utworzona ani wypełniona, a żadna relacja nie zostanie utworzona.
W poniższym przykładzie użyto dostawcy MSDataShape do wygenerowania kolumny rozdziału zamówień dla każdego klienta na liście klientów. Element A DataSet
jest następnie wypełniany danymi.
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");
}
Po zakończeniu Fill
DataSet
operacji zawiera dwie tabele: Customers
i CustomersOrders
, gdzie CustomersOrders
reprezentuje kolumnę z rozdziałami. Dodatkowa kolumna o nazwie Orders
zostanie dodana do Customers
tabeli, a do tabeli zostanie dodana dodatkowa kolumna CustomersOrders
o nazwieCustomersOrders
. Kolumna Orders
w Customers
tabeli jest ustawiona na automatyczne zwiększanie. Element DataRelation
, CustomersOrders
jest tworzony przy użyciu kolumn dodanych do tabel Customers
jako tabeli nadrzędnej. W poniższych tabelach przedstawiono kilka przykładowych wyników.
TableName: Klienci
CustomerID (Identyfikator klienta) | CompanyName | Zamówienia |
---|---|---|
ALFKI | Alfreds Futterkiste | 0 |
ANATR | Ana Trujillo Emparedados y helados | 1 |
TableName: CustomersOrders
CustomerID (Identyfikator klienta) | OrderID | CustomersOrders (Zamówienia klientów) |
---|---|---|
ALFKI | 10643 | 0 |
ALFKI | 10692 | 0 |
ANATR | 10308 | 1 |
ANATR | 10625 | 1 |