Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il ADO.NET DataSet è una rappresentazione residente in memoria dei dati che fornisce un modello di programmazione relazionale coerente indipendentemente dall'origine dati. Rappresenta DataSet
un set completo di dati che include tabelle, vincoli e relazioni tra le tabelle. Poiché il DataSet
è indipendente dall'origine dati, un DataSet
può includere dati locali all'applicazione e dati da più origini dati. L'interazione con le origini dati esistenti viene controllata tramite .DataAdapter
La SelectCommand
proprietà di DataAdapter
è un Command
oggetto che recupera i dati dalla fonte dati. Le proprietà InsertCommand
, UpdateCommand
e DeleteCommand
di DataAdapter
sono Command
oggetti che gestiscono gli aggiornamenti ai dati nell'origine dati secondo le modifiche effettuate sui dati in DataSet
. Queste proprietà sono descritte in modo più dettagliato in Aggiornamento delle origini dati con DataAdapter.
Il metodo Fill
di DataAdapter
viene utilizzato per popolare un DataSet
con i risultati di SelectCommand
di DataAdapter
.
Fill
accetta come argomenti un DataSet
oggetto da popolare e un DataTable
oggetto oppure il nome dell'oggetto DataTable
da riempire con le righe restituite da SelectCommand
.
Annotazioni
L'utilizzo di DataAdapter
per recuperare tutte le tabelle richiede tempo, soprattutto se nella tabella sono presenti molte righe. Ciò è dovuto al fatto che l'accesso al database, l'individuazione e l'elaborazione dei dati e quindi il trasferimento dei dati al client richiede molto tempo. Trasferire tutta la tabella al client blocca anche tutte le righe sul server. Per migliorare le prestazioni, è possibile usare la WHERE
clausola per ridurre notevolmente il numero di righe restituite al client. È anche possibile ridurre la quantità di dati restituiti al client elencando in modo esplicito le colonne richieste nell'istruzione SELECT
. Un'altra buona soluzione consiste nel recuperare le righe in batch (ad esempio diverse centinaia di righe alla volta) e recuperare il batch successivo solo al termine del batch corrente.
Il Fill
metodo usa l'oggetto DataReader
in modo implicito per restituire i nomi e i tipi di colonna utilizzati per creare le tabelle in DataSet
e i dati per popolare le righe delle tabelle in DataSet
. Le tabelle e le colonne vengono create solo se non esistono già; in caso contrario Fill
, usa lo schema esistente DataSet
. I tipi di colonna vengono creati come tipi .NET Framework in base alle tabelle nelle mappature dei tipi di dati in ADO.NET. Le chiavi primarie non vengono create a meno che non esistano nell'origine dati e DataAdapter
.MissingSchemaAction
è impostato su MissingSchemaAction
.AddWithKey
. Se Fill
rileva che esiste una chiave primaria per una tabella, sovrascriverà i dati nell'oggetto DataSet
con i dati dell'origine dati per le righe in cui i valori della colonna chiave primaria corrispondono a quelli della riga restituita dall'origine dati. Se non viene trovata alcuna chiave primaria, i dati vengono aggiunti alle tabelle di DataSet
.
Fill
usa tutti i mapping che possono esistere quando si popola l'oggetto DataSet
(vedere DataAdapter DataTable e Mapping DataColumn).
Annotazioni
Se SelectCommand
restituisce i risultati di un OUTER JOIN, DataAdapter
non imposta un valore PrimaryKey
per l'elemento risultante DataTable
. È necessario definire manualmente PrimaryKey
per assicurarsi che le righe duplicate vengano risolte correttamente. Per altre informazioni, vedere Definizione delle chiavi primarie.
Nell'esempio di codice seguente viene creata un'istanza di SqlDataAdapter che utilizza SqlConnection per il database Northwind
Microsoft SQL Server e popola un DataTable con l'elenco dei clienti in un DataSet
. L'istruzione SQL e SqlConnection argomenti passati al costruttore SqlDataAdapter vengono utilizzati per creare la proprietà SelectCommand di SqlDataAdapter.
Esempio
' 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");
Annotazioni
Il codice illustrato in questo esempio non apre e chiude in modo esplicito il Connection
. Il metodo Fill
apre in modo implicito l'oggetto Connection
che il DataAdapter
utilizza se rileva che la connessione non è già aperta. Quando Fill
apre la connessione, chiude anche la connessione quando Fill
è completato. Ciò consente di semplificare il codice quando si gestisce una singola operazione, come Fill
o Update
. Tuttavia, se si eseguono più operazioni che richiedono una connessione aperta, è possibile migliorare le prestazioni dell'applicazione chiamando in modo esplicito il Open
metodo di Connection
, eseguendo le operazioni sull'origine dati e quindi chiamando il Close
metodo dell'oggetto Connection
. È consigliabile provare a mantenere aperte le connessioni all'origine dati per il minor tempo possibile per liberare risorse da utilizzare da parte di altre applicazioni client.
Più set di risultati
Se il DataAdapter
incontra più set di risultati, crea più tabelle in DataSet
. Alle tabelle viene assegnato un nome predefinito incrementale di TableN, a partire da "Table" per Table0. Se un nome di tabella viene passato come argomento al Fill
metodo , alle tabelle viene assegnato un nome predefinito incrementale di TableNameN, a partire da "TableName" per TableName0.
Popolamento di un set di dati da più dataadapter
È possibile usare un numero qualsiasi di DataAdapter
oggetti con un oggetto DataSet
. Ognuno di essi DataAdapter
può essere usato per riempire uno o più DataTable
oggetti e risolvere gli aggiornamenti nell'origine dati pertinente.
DataRelation
e Constraint
oggetti possono essere aggiunti all'oggetto DataSet
localmente, permettendo di correlare i dati da origini dati diverse. Ad esempio, un DataSet
può contenere dati da un database di Microsoft SQL Server, un database IBM DB2 esposto tramite OLE DB e un'origine dati che trasmette XML. Uno o più DataAdapter
oggetti possono gestire la comunicazione con ogni origine dati.
Esempio
Nell'esempio di codice seguente viene popolato un elenco di clienti dal Northwind
database in Microsoft SQL Server e un elenco di ordini dal Northwind
database archiviato in Microsoft Access 2000. Le tabelle compilate sono correlate con un DataRelation
e l'elenco dei clienti viene quindi visualizzato insieme agli ordini che li riguardano. Per altre informazioni sugli DataRelation
oggetti, vedere Aggiunta di oggetti DataRelations e Esplorazione di 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"]);
}
Tipo decimale di SQL Server
Per impostazione predefinita, DataSet
archivia i dati utilizzando i tipi di dati del .NET Framework. Per la maggior parte delle applicazioni, questi forniscono una rappresentazione pratica delle informazioni sull'origine dati. Tuttavia, questa rappresentazione può causare un problema quando il tipo di dati nell'origine dati è un tipo di dati decimale o numerico di SQL Server. Il tipo di dati .NET Framework decimal
consente un massimo di 28 cifre significative, mentre il tipo di dati di SQL Server decimal
consente 38 cifre significative. Se SqlDataAdapter
stabilisce durante un'operazione Fill
che la precisione di un campo SQL Server decimal
è maggiore di 28 caratteri, la riga corrente non viene aggiunta al DataTable
. L'evento FillError
si verifica invece, che consente di determinare se si verificherà una perdita di precisione e rispondere in modo appropriato. Per altre informazioni sull'evento FillError
, vedere Gestione degli eventi DataAdapter. Per ottenere il valore di SQL Server decimal
, è anche possibile usare un SqlDataReader oggetto e chiamare il GetSqlDecimal metodo .
ADO.NET 2.0 ha introdotto il supporto avanzato per System.Data.SqlTypes in DataSet
. Per altre informazioni, vedere SqlTypes e DataSet.
Capitoli OLE DB
I set di righe gerarchici o i capitoli (tipo DBTYPE_HCHAPTER
OLE DB , tipo adChapter
ADO ) possono essere usati per riempire il contenuto di un oggetto DataSet
. Quando il OleDbDataAdapter rileva una colonna capitolata durante un'operazione Fill
, viene creato un DataTable
per tale colonna e questa tabella viene riempita con le colonne e le righe del capitolo. La tabella creata per la colonna con capitoli viene denominata usando sia il nome della tabella padre che il nome della colonna con capitoli nel formato "ParentTableNameChapteredColumnName". Se esiste già una tabella in DataSet
che corrisponde al nome della colonna con capitoli, la tabella corrente viene compilata con i dati del capitolo. Se non è presente alcuna colonna in una tabella esistente che corrisponde a una colonna trovata nel capitolo, viene aggiunta una nuova colonna.
Prima che le tabelle nell'oggetto DataSet
vengano riempite con i dati nelle colonne con capitoli, viene creata una relazione tra le tabelle padre e figlio del set di righe gerarchico aggiungendo una colonna integer alla tabella padre e figlio, impostando la colonna padre su incremento automatico e creando un DataRelation
oggetto utilizzando le colonne aggiunte da entrambe le tabelle. La relazione aggiunta viene denominata utilizzando i nomi delle colonne della tabella padre e del capitolo nel formato "ParentTableNameChapterColumnName".
Si noti che la colonna correlata esiste solo in DataSet
. I riempimenti successivi dall'origine dati possono causare l'aggiunta di nuove righe alle tabelle invece di fondere le modifiche nelle righe esistenti.
Si noti che, se si utilizza l'overload DataAdapter.Fill
che prende un DataTable
, verrà riempita solo quella tabella. Alla tabella verrà comunque aggiunta una colonna integer con incremento automatico, ma non verrà creata o compilata alcuna tabella figlio e non verrà creata alcuna relazione.
Nell'esempio seguente viene usato il provider MSDataShape per generare una colonna capitolo di ordini per ogni cliente in un elenco di clienti. Un DataSet
viene quindi popolato con i dati.
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");
}
Al termine dell'operazione Fill
, DataSet
contiene due tabelle: Customers
e CustomersOrders
, dove CustomersOrders
rappresenta la colonna con capitoli. Viene aggiunta una colonna aggiuntiva denominata Orders
alla Customers
tabella e viene aggiunta una colonna aggiuntiva denominata CustomersOrders
alla CustomersOrders
tabella. La Orders
colonna nella Customers
tabella è impostata su incremento automatico. Un DataRelation
oggetto , CustomersOrders
viene creato usando le colonne aggiunte alle tabelle con Customers
come tabella padre. Le tabelle seguenti mostrano alcuni risultati di esempio.
TableName: Clienti
ID Cliente | NomeAzienda | Ordini |
---|---|---|
ALFKI | Alfreds Futterkiste | 0 |
ANATR | Ana Trujillo Panini e gelati | 1 |
TableName: OrdiniClienti
ID Cliente | OrderID | OrdiniClienti |
---|---|---|
ALFKI | 10643 | 0 |
ALFKI | 10692 | 0 |
ANATR | 10308 | 1 |
ANATR | 10625 | 1 |