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.
Quando la proprietà SelectCommand
viene specificata dinamicamente al momento dell'esecuzione, ad esempio tramite uno strumento di query che accetta un comando testuale dall'utente, potrebbe non essere possibile specificare InsertCommand
, UpdateCommand
, o DeleteCommand
al momento della progettazione. Se il DataTable è mappato su o viene generato da una singola tabella di database, è possibile sfruttare l'oggetto DbCommandBuilder per generare automaticamente il DeleteCommand
, il InsertCommand
e il UpdateCommand
del DbDataAdapter.
Come requisito minimo, è necessario impostare la proprietà affinché la SelectCommand
generazione automatica dei comandi funzioni. Lo schema della SelectCommand
tabella recuperato dalla proprietà determina la sintassi delle istruzioni INSERT, UPDATE e DELETE generate automaticamente.
Il DbCommandBuilder deve eseguire il SelectCommand
per poter restituire i metadati necessari per costruire i comandi SQL INSERT, UPDATE e DELETE. Di conseguenza, è necessario un ulteriore viaggio all'origine dati e ciò può ostacolare le prestazioni. Per ottenere prestazioni ottimali, specificare i comandi in modo esplicito anziché usare .DbCommandBuilder
È inoltre necessario che SelectCommand
restituisca almeno una chiave primaria o una colonna univoca. Se non sono presenti, viene generata un'eccezione InvalidOperation
e i comandi non vengono generati.
Quando associato a DataAdapter
, l'oggetto DbCommandBuilder genera automaticamente le proprietà InsertCommand
, UpdateCommand
e DeleteCommand
di DataAdapter
se sono riferimenti null. Se esiste già un Command
oggetto per una proprietà, viene utilizzato l'oggetto esistente Command
.
Le viste di database create unendo due o più tabelle insieme non vengono considerate una singola tabella di database. In questa istanza non è possibile utilizzare il DbCommandBuilder per generare automaticamente comandi; è necessario specificare i comandi in modo esplicito. Per informazioni sull'impostazione esplicita dei comandi per applicare gli aggiornamenti a un'origine dati DataSet
, vedere Aggiornamento di origini dati con DataAdapters.
Potresti voler mappare i parametri di output alla riga aggiornata di un oggetto DataSet
. Un'attività comune consiste nel recuperare il valore di un campo identità generato automaticamente o di una marca temporale dall'origine dei dati. Il DbCommandBuilder di default non eseguirà il mapping dei parametri di output alle colonne in una riga aggiornata. In questa istanza è necessario specificare il comando in modo esplicito. Per un esempio di associazione di un campo Identity generato automaticamente a una colonna di una riga aggiunta, vedere Recupero di valori identity o numerazione automatica.
Regole per i comandi generati automaticamente
Nella tabella seguente vengono mostrate le regole per la generazione automatica dei comandi.
Comando | Regola |
---|---|
InsertCommand |
Inserisce una riga nell'origine dati per ogni riga della tabella con un valore di RowState pari a Added. Inserisce valori per tutte le colonne aggiornabili, ma non per colonne quali identità, espressioni o timestamp. |
UpdateCommand |
Aggiorna le righe nell'origine dati per tutte le righe della tabella con un RowState di Modified. Aggiorna i valori di tutte le colonne ad eccezione delle colonne che non sono aggiornabili, ad esempio identità o espressioni. Aggiorna tutte le righe in cui i valori di colonna nell'origine dati corrispondono ai valori della colonna chiave primaria della riga e dove le colonne rimanenti nell'origine dati corrispondono ai valori originali della riga. Per altre informazioni, vedere "Modello di concorrenza ottimistica per aggiornamenti ed eliminazioni" più avanti in questo argomento. |
DeleteCommand |
Elimina le righe nell'origine dati per tutte le righe della tabella con un valore di RowState pari a Deleted. Elimina tutte le righe in cui i valori della colonna corrispondono ai valori della colonna chiave primaria della riga e in cui le colonne rimanenti nell'origine dati corrispondono ai valori originali della riga. Per altre informazioni, vedere "Modello di concorrenza ottimistica per aggiornamenti ed eliminazioni" più avanti in questo argomento. |
Modello di concorrenza ottimistica per aggiornamenti ed eliminazioni
La logica per la generazione automatica dei comandi per le istruzioni UPDATE e DELETE si basa sulla concorrenza ottimistica, ovvero i record non sono bloccati per la modifica e possono essere modificati da altri utenti o processi in qualsiasi momento. Poiché un record potrebbe essere stato modificato dopo che è stato restituito dall'istruzione SELECT, ma prima dell'emissione dell'istruzione UPDATE o DELETE, l'istruzione UPDATE o DELETE generata automaticamente contiene una clausola WHERE, specificando che una riga viene aggiornata solo se contiene tutti i valori originali e non è stata eliminata dall'origine dati. Questa operazione viene eseguita per evitare di sovrascrivere nuovi dati. Quando un aggiornamento generato automaticamente tenta di aggiornare una riga eliminata o che non contiene i valori originali trovati in DataSet, il comando non influisce sui record e viene generata un'eccezione DBConcurrencyException .
Se si desidera completare l'istruzione UPDATE o DELETE indipendentemente dai valori originali, è necessario impostare in modo esplicito il UpdateCommand
per il DataAdapter
e non basarsi sulla generazione automatica dei comandi.
Limitazioni della logica di generazione automatica dei comandi
Le limitazioni seguenti si applicano alla generazione automatica dei comandi.
Solo tabelle non correlate
La logica di generazione automatica dei comandi genera istruzioni INSERT, UPDATE o DELETE per tabelle autonome senza tenere conto delle relazioni con altre tabelle nell'origine dati. Di conseguenza, è possibile che si verifichi un errore quando si chiama Update
per inviare modifiche per una colonna che partecipa a un vincolo di chiave esterna nel database. Per evitare questa eccezione, non utilizzare DbCommandBuilder per l'aggiornamento delle colonne coinvolte in un vincolo di chiave esterna; specificare invece esplicitamente le istruzioni utilizzate per eseguire l'operazione.
Nomi di tabella e colonna
La logica di generazione automatica dei comandi può non riuscire se i nomi di colonna o di tabella contengono caratteri speciali, ad esempio spazi, punti, virgolette o altri caratteri non alfanumerici, anche se delimitati da parentesi quadre. A seconda del provider, l'impostazione dei parametri QuotePrefix e QuoteSuffix può consentire alla logica di generazione di elaborare gli spazi, ma non può gestire correttamente i caratteri speciali. Sono supportati nomi di tabella completi sotto forma di catalog.schema.table .
Uso di CommandBuilder per generare automaticamente un'istruzione SQL
Per generare automaticamente istruzioni SQL per un DataAdapter
oggetto , impostare prima la SelectCommand
proprietà di DataAdapter
, quindi creare un CommandBuilder
oggetto e specificare come argomento per DataAdapter
il quale CommandBuilder
genererà automaticamente istruzioni SQL.
' Assumes that connection is a valid SqlConnection object
' inside of a Using block.
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT * FROM dbo.Customers", connection)
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(adapter)
builder.QuotePrefix = "["
builder.QuoteSuffix = "]"
// Assumes that connection is a valid SqlConnection object
// inside of a using block.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
Modifica del comando Select
Se si modifica il CommandText
del SelectCommand
dopo che i comandi INSERT, UPDATE o DELETE sono stati generati automaticamente, potrebbe verificarsi un'eccezione. Se l'oggetto modificato SelectCommand.CommandText
contiene informazioni sullo schema non coerenti con l'oggetto SelectCommand.CommandText
utilizzato quando i comandi di inserimento, aggiornamento o eliminazione sono stati generati automaticamente, le chiamate future al DataAdapter.Update
metodo potrebbero tentare di accedere alle colonne che non esistono più nella tabella corrente a cui fa riferimento il SelectCommand
e verrà generata un'eccezione.
È possibile aggiornare le informazioni sullo schema usate da CommandBuilder
per generare automaticamente i comandi chiamando il RefreshSchema
metodo di CommandBuilder
.
Per sapere quale comando è stato generato automaticamente, è possibile ottenere un riferimento ai comandi generati automaticamente usando i metodi GetInsertCommand
, GetUpdateCommand
e GetDeleteCommand
dell'oggetto CommandBuilder
e controllando la proprietà CommandText
del comando associato.
Nell'esempio di codice seguente viene scritto nella console il comando di aggiornamento generato automaticamente.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
Nell'esempio seguente viene ricreata la Customers
tabella nel custDS
set di dati. Il metodo RefreshSchema viene chiamato per aggiornare i comandi generati automaticamente con queste nuove informazioni sulla colonna.
' Assumes an open SqlConnection and SqlDataAdapter inside of a Using block.
adapter.SelectCommand.CommandText = _
"SELECT CustomerID, ContactName FROM dbo.Customers"
builder.RefreshSchema()
custDS.Tables.Remove(custDS.Tables("Customers"))
adapter.Fill(custDS, "Customers")
// Assumes an open SqlConnection and SqlDataAdapter inside of a using block.
adapter.SelectCommand.CommandText =
"SELECT CustomerID, ContactName FROM dbo.Customers";
builder.RefreshSchema();
custDS.Tables.Remove(custDS.Tables["Customers"]);
adapter.Fill(custDS, "Customers");