Cenni preliminari sul salvataggio dei dati

Aggiornamento: novembre 2007

Il salvataggio dei dati è il processo mediante il quale i dati modificati di un'applicazione vengono salvati in modo permanente nell'archivio dati originale, in genere un database relazionale come SQL Server.

Poiché un dataset è in pratica una cache, cioè una copia in memoria, di dati, la scrittura delle informazioni nell'origine dati iniziale e la modifica dei dati nel dataset costituiscono processi distinti. Per inviare i dati aggiornati nei dataset al database, è possibile chiamare uno dei metodi Update di un oggetto TableAdapter oppure chiamare uno dei metodi DBDirect di TableAdapter.

Per ulteriori informazioni sull'invio delle modifiche presenti in un dataset al database, vedere Procedura: aggiornare i dati mediante un TableAdapter e Procedura: salvare le modifiche di un dataset in un database.

Visual Studio 2008 fornisce un nuovo componente TableAdapterManager che semplifica la procedura di salvataggio dei dati nelle tabelle correlate, garantendo che i salvataggi vengano eseguiti nell'ordine corretto in base ai vincoli di chiave esterna definiti nel database. Per ulteriori informazioni, vedere Cenni preliminari sull'aggiornamento gerarchico.

Per informazioni sulla modifica di dati nel dataset, vedere Modifica di dati nell'applicazione.

Aggiornamenti in due fasi

L'aggiornamento di un'origine dati mediante un dataset è un processo in due fasi: la consiste nell'aggiornare il dataset con nuove informazioni, ovvero nuovi record, record modificati o record eliminati. Se l'applicazione riguarda esclusivamente il dataset, cioè se, ad esempio, dopo aver aggiornato il dataset, lo si invia a un'altra applicazione, che ne svolgerà un'ulteriore elaborazione, l'aggiornamento può considerarsi terminato.

Nota:

Grazie all'architettura di associazione dei dati dei Windows Form è possibile inviare le modifiche da controlli associati a dati al dataset e pertanto non è più necessario aggiornare esplicitamente il dataset con il proprio codice. Per ulteriori informazioni, vedere Associazione ai dati di Windows Form.

Se si sta aggiornando un'origine dati, quale un database, il secondo passaggio consiste nell'inviare le modifiche dal dataset all'origine dati iniziale. In altre parole, tramite il processo di aggiornamento del dataset le modifiche non vengono scritte anche in un'origine dati sottostante, ma è necessario effettuare questo secondo passaggio in modo esplicito. In genere, tale operazione viene svolta chiamando il metodo Update dello stesso TableAdapter o adattatore dati utilizzato per compilare il dataset. È anche possibile, tuttavia, utilizzare altri adattatori, ad esempio per spostare i dati da un'origine dati all'altra o per aggiornare più origini dati.

Processo di aggiornamento in due fasi e ruolo di DataRowVersion in un aggiornamento eseguito correttamente

Aggiornamenti di Dataset di Visual Basic

Dal punto di vista strutturale, i dati di un dataset sono disponibili come serie di insiemi. Nei dataset sono contenuti insiemi di tabelle, che, a loro volta, contengono insiemi di righe. Le tabelle vengono esposte come un insieme dell'oggetto DataSet e i record sono disponibili nell'insieme Rows degli oggetti DataTable. È possibile apportare delle modifiche ai dati di un dataset semplicemente modificando questi insiemi mediante i relativi metodi base. Tuttavia, se si desidera aggiornare un'origine dati sottostante, sarà necessario utilizzare i metodi progettati specificamente per la modifica del dataset.

Per rimuovere un record da una tabella dati, ad esempio, è possibile chiamare il metodo RemoveAt dell'insieme Rows della tabella, che elimina fisicamente il record dal dataset. Se si sta utilizzando il dataset solo come un archivio strutturato per i dati e non si ha intenzione di trasmettere le informazioni di modifica a un'altra applicazione, questo tipo di modifica degli insiemi è un metodo accettabile per l'aggiornamento di un dataset.

Tuttavia, per inviare le modifiche a un'origine dati o a un'altra applicazione, è necessario conservare le informazioni relative alla modifica, ovvero i metadati, per ciascun aggiornamento. In seguito, una volta inviate le modifiche all'origine dati o all'applicazione, il processo disporrà delle informazioni necessarie per l'individuazione e l'aggiornamento dei record appropriati. Se ad esempio si elimina un record dal dataset, sarà necessario conservarne comunque le informazioni nel dataset. In questo modo, quando viene richiamato il metodo DeleteCommand del TableAdapter, le informazioni della cronologia saranno sufficienti a individuare il record originale nell'origine dati per consentirne l'eliminazione. Per ulteriori informazioni, vedere più avanti la sezione "Gestione delle informazioni sulle modifiche" e

Unione di dataset

È possibile aggiornare il contenuto di un dataset unendo, cioè copiando il contenuto di un dataset, definito dataset di origine, nel dataset chiamante, definito dataset di destinazione. Quando si uniscono i dataset, al dataset di destinazione vengono aggiunti i nuovi record del dataset di origine. Inoltre, le colonne supplementari del dataset di origine vengono aggiunte al dataset di destinazione. L'unione dei dataset è particolarmente utile quando si dispone di un dataset locale e si ottiene un secondo dataset da un'altra applicazione o da un componente quale un servizio Web XML. È utile inoltre quando si desidera integrare dati da più dataset.

Quando si uniscono i dataset, è anche possibile passare un argomento Boolean facoltativo (preserveChanges) che indichi al metodo Merge se conservare o meno le modifiche esistenti nel dataset di destinazione. Poiché i dataset mantengono più versioni dei record, è importante tenere presente che l'unione interessa più versioni dei record. Nella tabella seguente è riportato un record presente in due dataset che verranno uniti:

DataRowVersion

Dataset di destinazione

Dataset di origine

Original

James Wilson

James C. Wilson

Current

Jim Wilson

James C. Wilson

La chiamata al metodo Merge presente nella tabella sopra riportata con preserveChanges=false targetDataset.Merge(sourceDataset) determina la situazione che segue:

DataRowVersion

Dataset di destinazione

Dataset di origine

Original

James C. Wilson

James C. Wilson

Current

James C. Wilson

James C. Wilson

La chiamata al metodo Merge con preserveChanges = true targetDataset.Merge(sourceDataset, true) determina la situazione che segue:

DataRowVersion

Dataset di destinazione

Dataset di origine

Original

James C. Wilson

James C. Wilson

Current

Jim Wilson

James C. Wilson

Attenzione:

Nello scenario preserveChanges = true, se in un record del dataset di destinazione viene chiamato il metodo RejectChanges, verranno ripristinati i dati originali del dataset di origine, il che significa che, se si tenta di aggiornare l'origine dati iniziale con il dataset di destinazione, potrebbe non essere possibile trovare la riga originale da aggiornare. È tuttavia possibile evitare che si verifichi una violazione di concorrenza compilando un altro dataset con i record aggiornati dall'origine dati e quindi eseguendo un'unione. Una violazione di concorrenza si verifica quando un altro utente modifica un record nell'origine dati dopo la compilazione del dataset. Per ulteriori informazioni, vedere Controllo della concorrenza in ADO.NET.

Vincoli di aggiornamento

Per apportare delle modifiche a una riga di dati esistente, si aggiungono o si aggiornano i dati nelle singole colonne. Se il dataset contiene dei vincoli, quali chiavi esterne o vincoli non nullable, è possibile che durante l'aggiornamento di un record, dopo aver terminato di aggiornare una colonna, ma prima di passare alla successiva, il record si trovi temporaneamente in stato di errore.

Per impedire violazioni anomale dei vincoli, è possibile sospendere temporaneamente i vincoli di aggiornamento, ottenendo un duplice effetto:

  • Si impedisce che venga generato un errore quando una colonna viene aggiornata prima di passare a un'altra.

  • Si sospende la generazione di determinati eventi di aggiornamento, che vengono spesso utilizzati per la convalida.

Una volta completato un aggiornamento, è possibile riattivare il controllo dei vincoli. In questo modo verranno riattivati e generati anche gli eventi di aggiornamento.

Nota:

Tramite l'architettura di associazione dati integrata nella griglia dei dati in Windows Form, il controllo dei vincoli viene sospeso finché lo stato attivo non passa all'esterno di una riga. Di conseguenza, non è più necessario chiamare esplicitamente i metodi BeginEdit, EndEdit o CancelEdit.

Quando viene richiamato il metodo Merge in un dataset, i vincoli vengono disattivati automaticamente. Quando l'unione è completa, se nel dataset sono presenti dei vincoli che non possono essere attivati, verrà generata un'eccezione ConstraintException. In questa situazione, la proprietà EnforceConstraints viene impostata su false e tutte le violazioni dei vincoli dovranno essere risolte prima di reimpostare la proprietà EnforceConstraints su true.

Una volta completato un aggiornamento, è possibile riattivare il controllo dei vincoli. In questo modo verranno riattivati e generati anche gli eventi di aggiornamento.

Per ulteriori informazioni sulla sospensione degli eventi, vedere Procedura: disattivare i vincoli durante il riempimento di un dataset.

Errori di aggiornamento dei dataset

Quando si aggiorna un record di un dataset, è possibile che si verifichi un errore. Può accadere ad esempio che i dati vengano scritti inavvertitamente in una colonna troppo lunga o appartenente al tipo di dati non corretto o con altri problemi di integrità. È inoltre possibile che i controlli di convalida specifici dell'applicazione generino degli errori personalizzati durante qualsiasi fase di un evento di aggiornamento. Per ulteriori informazioni, vedere Cenni preliminari sulla convalida dei dati.

Conservazione delle informazioni sulle modifiche

Le informazioni sulle modifiche apportate a un dataset vengono conservate in due modi: contrassegnando la riga che indica se il dataset è stato modificato (RowState) e conservando più copie di uno stesso record (DataRowVersion). Utilizzando queste informazioni, i processi saranno in grado di individuare le modifiche apportate al dataset e di inviare all'origine dati gli aggiornamenti appropriati.

Proprietà RowState

La proprietà RowState di un oggetto DataRow è un valore che fornisce informazioni sullo stato di una determinata riga di dati.

Nella tabella che segue sono riportati in modo dettagliato i possibili valori dell'enumerazione DataRowState.

Valore di DataRowState

Descrizione

Added

La riga è stata aggiunta come elemento all'insieme DataRowCollection. Una riga che presenta questo stato non ha una versione originale corrispondente, in quanto non esisteva nel momento in cui è stato chiamato l'ultimo metodo AcceptChanges.

Deleted

La riga è stata eliminata utilizzando il metodo Delete di un oggetto DataRow.

Detached

La riga è stata creata ma non fa parte di alcun insieme DataRowCollection. Un oggetto DataRow presenta questo stato immediatamente dopo essere stato creato e prima di essere aggiunto a un insieme oppure se è stato rimosso da un insieme.

Modified

Un valore di colonna presente nella riga è stato modificato.

Unchanged

La riga non è stata modificata dal momento dell'ultima chiamata del metodo AcceptChanges.

Enumerazione DataRowVersion

Nei dataset sono conservate più versioni dei record. L'enumerazione DataRowVersion di un oggetto DataRow è un valore utilizzabile per restituire una determinata versione di un oggetto DataRow.

Nella tabella che segue sono riportati in modo dettagliato i possibili valori dell'enumerazione DataRowVersion.

Valore di DataRowVersion

Descrizione

Current

La versione corrente di un record contiene tutte le modifiche apportate al record dall'ultima volta in cui è stato chiamato il metodo AcceptChanges. Se la riga è stata eliminata, non vi sarà alcuna versione corrente.

Default

Valore predefinito di un record, definito dall'origine dati o dallo schema del dataset.

Original

La versione originale di un record è una copia del record con lo stato che il record presentava dopo l'ultima applicazione delle modifiche nel dataset. In pratica, si tratta di solito della versione di un record letto da un'origine dati.

Proposed

Versione proposta di un record disponibile temporaneamente, mentre è ancora in corso un aggiornamento, cioè tra la chiamata del metodo BeginEdit e la chiamata del metodo EndEdit. In genere si accede alla versione proposta di un record in un gestore per un evento quale RowChanging. Richiamando il metodo CancelEdit vengono annullate le modifiche e viene eliminata la versione proposta della riga di dati.

La versione originale e quella corrente sono utili quando le informazioni sull'aggiornamento vengono trasmesse a un'origine dati. In genere, quando viene inviato un aggiornamento all'origine dati, le nuove informazioni per il database sono contenute nella versione corrente di un record e le informazioni della versione originale vengono utilizzate per individuare il record da aggiornare. Nel caso in cui, ad esempio, viene modificata la chiave primaria di un record, è necessario un metodo per individuare il record appropriato nell'origine dati, in modo da aggiornarlo con le modifiche. Se non esistesse alcuna versione originale, il record verrebbe molto probabilmente aggiunto all'origine dati, determinando così non solo la presenza di un record supplementare indesiderato, ma anche di un record impreciso e non aggiornato. Le due versioni vengono utilizzate inoltre per il controllo di concorrenza: è possibile confrontare la versione originale con un record dell'origine dati per determinare se il record ha subito delle modifiche dal momento in cui è stato caricato nel dataset. Per ulteriori informazioni, vedere Controllo della concorrenza in ADO.NET.

La versione proposta è utile quando è necessario eseguire una convalida prima di applicare effettivamente le modifiche al dataset.

Anche se i record sono stati modificati, non sempre sono presenti le versioni originali o correnti della riga in questione. Quando si inserisce una nuova riga nella tabella non è presente alcuna versione originale, ma solo una versione corrente. Allo stesso modo, se si elimina una riga chiamando il metodo Delete della tabella, sarà presente una versione originale, ma non una versione corrente.

È possibile verificare l'esistenza di una determinata versione di un record eseguendo una query relativa alla proprietà HasVersion della riga di dati. Per accedere a una o all'altra versione di un record, passare il valore di enumerazione DataRowVersion come argomento facoltativo quando si richiede il valore di una colonna.

Recupero dei record modificati

È normale che non tutti i record di un dataset vengano aggiornati. È ad esempio possibile che un utente utilizzi un controllo DataGridView di Windows Form nel quale vengono visualizzati molti record, ma che ne aggiorni solo alcuni, ne elimini uno e inserisca un nuovo record. Per i dataset e le tabelle dati è disponibile un metodo (GetChanges) per restituire solo le righe che sono state modificate.

È possibile creare sottoinsiemi dei record modificati utilizzando il metodo GetChanges della tabella dati (GetChanges) o dello stesso dataset (GetChanges). Se si chiama il metodo per la tabella dati, verrà restituita una copia della tabella contenente solo i record modificati. Allo stesso modo, chiamando il metodo nel dataset, verrà restituito un nuovo dataset contenente esclusivamente i record modificati. Utilizzando GetChanges da solo verranno restituiti tutti i record modificati. Al contrario, passando al metodo GetChanges l'enumerazione DataRowState desiderata come parametro, sarà possibile specificare il sottoinsieme di record modificati desiderato: nuovi record aggiunti, record contrassegnati per l'eliminazione, record disconnessi o record modificati.

Il recupero di un sottoinsieme di record modificati è particolarmente utile quando si desidera inviare i record a un altro componente per l'elaborazione. Anziché inviare l'intero dataset, è possibile ridurre il sovraccarico di comunicazione con l'altro componente recuperando solo i record necessari. Per ulteriori informazioni, vedere Procedura: recuperare le righe modificate.

Applicazione delle modifiche nel dataset

Quando vengono apportate modifiche al dataset, viene impostata la proprietà RowState delle righe modificate. La versione originale e quella corrente dei record vengono definite, gestite e rese disponibili all'utente mediante la proprietà RowVersion. I metadati memorizzati in queste proprietà e che rappresentano le modifiche sono necessari per inviare all'origine dati gli aggiornamenti appropriati.

Se le modifiche riflettono lo stato corrente dell'origine dati, non sarà più necessario conservare queste informazioni. In genere esistono due situazioni in cui il dataset e la relativa origine sono sincronizzati:

  • Immediatamente dopo aver caricato le informazioni nel dataset, vale a dire quando i dati vengono letti dall'origine.

  • Dopo aver inviato le modifiche dal dataset all'origine dati, ma non prima, poiché in questo caso andrebbero perdute le informazioni di modifica necessarie per inviare le modifiche al database.

È possibile applicare le modifiche in sospeso al dataset chiamando il metodo AcceptChanges. Di solito in un'applicazione il metodo AcceptChanges viene chiamato nei casi seguenti:

  • Dopo che il dataset è stato caricato. Se si carica un dataset chiamando il metodo Fill di un oggetto TableAdapter, l'adattatore eseguirà automaticamente il commit delle modifiche. Tuttavia, se si carica un dataset unendovi un altro dataset, sarà necessario eseguire manualmente il commit delle modifiche.

    Nota:

    Per impedire che l'adattatore esegua il commit automatico delle modifiche quando si chiama il metodo Fill, è possibile impostare su false la proprietà AcceptChangesDuringFill dell'adattatore. Se impostata su false, la proprietà RowState di ciascuna riga inserita durante la compilazione verrà impostata su Added.

  • Dopo aver inviato le modifiche del dataset a un altro processo, ad esempio a un servizio Web.

    Attenzione:

    Se viene eseguito il commit delle modifiche in questo modo, tutte le informazioni di modifica verranno eliminate. Non applicare le modifiche finché non sono state svolte eventuali operazioni per le quali è necessario conoscere le modifiche apportate al dataset.

Con questo metodo vengono effettuate le seguenti operazioni:

Il metodo AcceptChanges è disponibile a tre livelli. È possibile chiamarlo su un oggetto DataRow, applicando così le modifiche solo alla riga in questione. È inoltre possibile chiamarlo su un oggetto DataTable per applicare le modifiche a tutte le righe di una tabella, oppure sull'oggetto DataSet per applicare tutte le modifiche in sospeso di tutti i record di tutte le tabelle del dataset.

Nella tabella seguente vengono descritte le modifiche applicate a seconda dell'oggetto sul quale viene chiamato il metodo.

Metodo

Risultato

DataRow.AcceptChanges

Le modifiche vengono applicate solo alla riga specifica

DataTable.AcceptChanges

Le modifiche vengono applicate a tutte le righe della tabella specifica

DataSet.AcceptChanges

Le modifiche vengono applicate a tutte le righe di tutte le tabelle del dataset

Nota:

Se si carica un dataset chiamando il metodo Fill di un oggetto TableAdapter, non è necessario accettare in modo esplicito le modifiche. Per impostazione predefinita, infatti, il metodo Fill chiama il metodo AcceptChanges dopo aver terminato l'inserimento dei dati nella tabella dati.

Un metodo correlato, RejectChanges, annulla l'effetto delle modifiche copiando di nuovo la versione Original sulla versione Current dei record e impostando nuovamente la proprietà RowState di ciascun record su Unchanged.

Convalida dei dati

Per verificare che i dati presenti nell'applicazione soddisfino i requisiti dei processi ai quali vengono passati, è spesso necessario aggiungere un processo di convalida, in modo da assicurarsi che l'immissione dei dati in un form da parte di un utente sia corretta, convalidare i dati inviati all'applicazione da un'altra applicazione o persino verificare che le informazioni calcolate all'interno del componente rispettino i vincoli dell'origine dati e i requisiti dell'applicazione.

È possibile convalidare i dati in diversi modi:

  • A livello aziendale, aggiungendo all'applicazione il codice per la convalida dei dati. Il dataset è uno degli oggetti in cui è possibile eseguire questa operazione. La scelta di utilizzare il dataset offre alcuni dei vantaggi della convalida back-end, quali la possibilità di convalidare le modifiche man mano che i valori di righe e di colonne vengono modificati. Per ulteriori informazioni, vedere Cenni preliminari sulla convalida dei dati.

  • A livello di presentazione, aggiungendo la convalida ai form. Per ulteriori informazioni, vedere Convalida dell'input utente in Windows Form.

  • Nel back-end dei dati, inviando i dati all'origine dati, ad esempio al database, e consentendo all'origine dati di accettarli o rifiutarli. Se si sta utilizzando un database che dispone di funzionalità complesse per la convalida dei dati e la visualizzazione delle informazioni sugli errori, questo può essere un approccio pratico, poiché consente di convalidare i dati indipendentemente dalla loro provenienza. Tuttavia, tale approccio potrebbe non soddisfare i requisiti di convalida specifici dell'applicazione. Inoltre, se si utilizza l'origine dati per convalidare i dati, potrebbero determinarsi numerosi percorsi di andata e ritorno all'origine dati, a seconda del modo in cui l'applicazione facilita la risoluzione degli errori di convalida generati dal back-end.

    Nota sulla sicurezza:

    Quando si utilizzano comandi dati con una proprietà CommandType impostata su Text, controllare attentamente le informazioni inviate da un client prima di passarle al database. Utenti malintenzionati potrebbero tentare di inviare istruzioni SQL modificate o aggiuntive con l'obiettivo di ottenere un accesso non autorizzato o di danneggiare il database. Prima di trasferire l'input di un utente in un database, si consiglia di verificare sempre che le informazioni siano valide. È opportuno utilizzare, quando possibile, query con parametri o stored procedure. Per ulteriori informazioni, vedere Cenni preliminari sugli attacchi tramite script.

Dopo aver modificato un dataset, è possibile trasmettere le modifiche apportate a un'origine dati. Nella maggior parte dei casi questa operazione viene eseguita chiamando il metodo Update di un TableAdapter (o adattatore dati). Il metodo scorre in un ciclo ciascun record presente in una tabella dati, per determinare l'eventuale tipo di aggiornamento necessario, quali aggiornamento, inserimento o eliminazione; viene quindi eseguito il comando appropriato.

Trasmissione di un aggiornamento all'origine dati

Per comprendere il modo in cui vengono effettuati gli aggiornamenti, si supponga che nell'applicazione venga utilizzato un dataset contenente una singola tabella dati. Nell'applicazione vengono recuperate due righe dal database. Dopo il recupero, la tabella dati in memoria presenterà questa struttura:

(RowState)     CustomerID   Name             Status
(Unchanged)    c200         Robert Lyon      Good
(Unchanged)    c400         Nancy Buchanan    Pending

Lo stato di Nancy Buchanan viene modificato in "Preferred". In seguito a questa modifica, il valore della proprietà RowState per quella riga passa da Unchanged a Modified. Il valore della proprietà RowState per la prima riga rimane invece Unchanged. La nuova struttura della tabella dati sarà la seguente:

(RowState)     CustomerID   Name             Status
(Unchanged)    c200         Robert Lyon      Good
(Modified)     c400         Nancy Buchanan    Preferred

Viene ora chiamato il metodo Update per trasmettere il dataset al database. Il metodo analizza una riga per volta. Per la prima riga, il metodo non trasmette alcuna istruzione SQL al database, poiché quella riga non ha subito modifiche da quando è stata recuperata originariamente dal database.

Per la seconda riga, invece, il metodo Update richiama automaticamente il comando dati corretto e lo trasmette al database. La sintassi specifica dell'istruzione SQL dipende dal sottolinguaggio SQL supportato dall'archivio dati sottostante. Tuttavia, è necessario notare le seguenti caratteristiche dell'istruzione SQL trasmessa:

  • L'istruzione SQL trasmessa è un'istruzione UPDATE. L'adattatore riconosce l'utilizzo di un'istruzione UPDATE in quanto il valore della proprietà RowState è Modified.

  • L'istruzione SQL trasmessa comprende una clausola WHERE, che indica che l'obiettivo dell'istruzione UPDATE è la riga con CustomerID = 'c400'. Questa parte dell'istruzione SELECT riconosce la riga di destinazione tra tutte le altre, poiché CustomerID è la chiave primaria della tabella di destinazione. Nel caso in cui valori necessari a identificare la riga fossero stati modificati, le informazioni per la clausola WHERE verranno derivate dalla versione originale del record (DataRowVersion.Original).

  • L'istruzione SQL trasmessa comprende la clausola SET, che consente di impostare i nuovi valori delle colonne modificate.

    Nota:

    Se la proprietà UpdateCommand dell'oggetto TableAdapter è stata impostata sul nome di una stored procedure, l'adattatore non creerà un'istruzione SQL. Al contrario, esso richiamerà la stored procedure con i parametri appropriati che sono stati passati.

Passaggio di parametri

In genere i valori relativi ai record da aggiornare nel database vengono passati utilizzando i parametri. Quando il metodo Update dell'oggetto TableAdapter esegue un'istruzione UPDATE, è necessario che vengano inseriti i valori del parametro. Il metodo recupera tali valori dall'insieme Parameters per il comando dati appropriato, in questo caso l'oggetto UpdateCommand presente nell'oggetto TableAdapter.

Se sono stati utilizzati gli strumenti di Visual Studio per generare un adattatore dati, nell'oggetto UpdateCommand sarà contenuto un insieme di parametri che corrisponderanno a ciascun segnaposto di parametro presente nell'istruzione.

La proprietà SqlParameter.SourceColumn di ogni parametro punta a una colonna nella tabella dati. La proprietà SourceColumn per i parametri au_id e Original_au_id, ad esempio, è impostata sulla colonna della tabella dati che contiene l'ID dell'autore. Quando viene eseguito il metodo Update dell'adattatore, la colonna dell'ID dell'autore viene letta dal record in fase di aggiornamento e vengono inseriti i valori nell'istruzione.

In un'istruzione UPDATE è necessario specificare sia i nuovi valori, cioè quelli che verranno scritti sul record, che i vecchi valori, per poter localizzare nel database il record che si desidera aggiornare. Esistono perciò due parametri per ciascun valore: uno per la clausola SET e un altro per la clausola WHERE. Per entrambi i parametri i dati vengono letti dal record che viene aggiornato, ma sono recuperate versioni diverse del valore della colonna, a seconda della proprietà SqlParameter.SourceVersion del parametro. Il parametro per la clausola SET recupera la versione corrente, mentre il parametro per la clausola WHERE recupera la versione originale.

Nota:

È inoltre possibile impostare direttamente nel codice i valori dell'insieme Parameters, come generalmente accade in un gestore eventi per l'evento RowChanging dell'adattatore dati. Per ulteriori informazioni, vedere Parametri dei comandi degli adattatori dati.

Aggiornamento di tabelle correlate

Se nel dataset sono contenute più tabelle, sarà necessario aggiornarle singolarmente chiamando separatamente il metodo Update di ciascun adattatore dati. Se le tabelle presentano una relazione padre-figlio, potrebbe essere necessario inviare gli aggiornamenti al database in un determinato ordine. Uno scenario comune è quello nel quale sono stati aggiunti sia i record padre che i record figlio correlati a un dataset, ad esempio, un nuovo record cliente e uno o più record di ordini correlati. Se nello stesso database sono attivate le regole di integrità relazionale, verranno generati degli errori nel caso in cui i nuovi record figlio vengano inviati al database prima della creazione del record padre.

Al contrario, se si eliminano i record correlati dal dataset, in genere sarà necessario inviare gli aggiornamenti in ordine inverso: prima per la tabella figlio e quindi per la tabella padre. In caso contrario, è probabile che nel database venga generato un errore, in quanto le regole di integrità referenziale impediranno l'eliminazione un record padre quando sono ancora presenti i record figlio correlati.

Una regola generale per inviare gli aggiornamenti relativi alle tabelle correlate consiste nel seguire questo ordine:

  1. Tabella figlio: eliminare i record.

  2. Tabella padre: inserire, aggiornare ed eliminare i record.

  3. Tabella figlio: inserire e aggiornare i record.

  4. Per ulteriori informazioni, vedere Procedura dettagliata: salvataggio di dati in un database (a più tabelle).

Controllo della concorrenza

Poiché i dataset sono disconnessi dall'origine dati, non vengono mantenuti blocchi sui record dell'origine dati. Di conseguenza, se si desidera aggiornare il database e se è importante per l'applicazione mantenere il controllo di concorrenza, sarà necessario risolvere le differenze tra i record del dataset con quelli presenti nel database. Sarebbe ad esempio possibile scoprire che i record del database sono stati modificati dopo l'ultima compilazione del dataset. In tal caso, è necessario eseguire una logica appropriata all'applicazione per specificare in che modo si desidera utilizzare i record del database o i record modificati presenti nel dataset. Per ulteriori informazioni, vedere Controllo della concorrenza in ADO.NET.

Vedere anche

Attività

Procedura: aggiornare i dati mediante un TableAdapter

Concetti

Cenni preliminari sugli oggetti TableAdapter

Altre risorse

Adattatori dati ADO.NET

Guida introduttiva all'accesso ai dati

Connessione ai dati in Visual Studio

Preparazione dell'applicazione al ricevimento di dati

Recupero di dati nell'applicazione

Visualizzazione di dati su form nelle applicazioni Windows

Modifica di dati nell'applicazione

Convalida dei dati

Salvataggio di dati