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ść SelectCommandDataAdapter obiektu to Command obiekt, który pobiera dane ze źródła danych. Właściwości InsertCommandDataAdapter , UpdateCommandi 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 FillDataAdapter 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 DataSetobiekcie , 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 DataAdapterustawiono wartość .MissingSchemaActionMissingSchemaActionAddWithKey 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_HCHAPTEROLE DB , typ adChapterADO ) 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 DataTablewartość , 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 FillDataSet 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, CustomersOrdersjest 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

Zobacz też