PRB: CommandBuilder ripristina lo stato originale di comandi modificati

Traduzione articoli Traduzione articoli
Identificativo articolo: 310366 - Visualizza i prodotti a cui si riferisce l?articolo.
Questo articolo è stato precedentemente pubblicato con il codice di riferimento I310366
Questo articolo è stato archiviato. L?articolo, quindi, viene offerto ?così come è? e non verrà più aggiornato.
Espandi tutto | Chiudi tutto

In questa pagina

Sintomi

L'oggetto CommandBuilder potrebbe ricreare un comando che l'utente tenta di modificare durante la chiamata successiva al metodo DataAdapter.Update e le modifiche apportate al comando potrebbero andare perse. Questo problema si verifica in presenza delle seguenti circostanze:
  • Se si associa un oggetto CommandBuilder a un oggetto DataAdapter.
  • Se si utilizza il metodo GetInsertCommand, GetUpdateCommand oppure GetDeleteCommand dell'oggetto CommandBuilder per assegnare in modo esplicito i comandi a DataAdapter.
  • Se si modifica uno dei comandi generati da CommandBuilder.
Quando si tenta di chiamare il metodo Update dell'oggetto DataAdapter, è possibile che venga visualizzato un messaggio di errore analogo al seguente:
Eccezione non gestita di tipo "System.Data.SqlClient.SqlException" in system.data.dll.

Cause

Questo problema si verifica perché CommandBuilder ripristina dinamicamente i comandi generati allo stato originale.

Risoluzione

Per risolvere il problema, utilizzare uno dei metodi seguenti:
  • Non modificare i comandi generati da CommandBuilder. CommandBuilder non altera gli oggetti Command creati dall'utente.
  • Copiare gli oggetti InsertCommand, DeleteCommand e UpdateCommand in un nuovo DataAdapter (vedere un esempio nella sezione Informazioni di questo articolo). La nuova variabile DataAdapter deve avere un ambito identico o inferiore alla vecchia variabile DataAdapter.
  • Non utilizzare affatto CommandBuilder. Scrivere i propri oggetti Command oppure utilizzare Visual Data Tools per farlo.

Status

Si tratta di un comportamento legato alla progettazione del prodotto.

Informazioni

Procedura per riprodurre il problema

  1. Creare un nuovo progetto di applicazione Windows in Visual Basic. In base all'impostazione predefinita, verrà aggiunto al progetto il Form1.
  2. Fare doppio clic sul form e aggiungere il codice seguente nella parte superiore della finestra del codice:
    Imports System.Data.SqlClient
  3. Aggiungere un controllo Button a Form1.
  4. Fare doppio clic sul pulsante e aggiungere il codice seguente all'evento Click:
    Dim cn As New SqlConnection()
            Dim custDS As New DataSet()
            Dim da1 As New SqlDataAdapter()
            Dim da2 As New SqlDataAdapter()
            Dim dr As DataRow
            Dim cb As SqlCommandBuilder
    
            cn.ConnectionString = "server=servername;database=northwind;uid=sa;pwd=password;"
            cn.Open()
            da1 = New SqlDataAdapter("select * from Customers", cn)
            cb = New SqlCommandBuilder(da1)
    
            da1.Fill(custDS, "Customers")
    
            'Get the original commands.
    
            da1.InsertCommand = cb.GetInsertCommand
            da1.DeleteCommand = cb.GetDeleteCommand
            da1.UpdateCommand = cb.GetUpdateCommand
    
            Debug.WriteLine("Original command length: " & da1.InsertCommand.CommandText.Length)
    
            'Modify the Insert command.
    
            da1.InsertCommand.CommandText = "select * from customers where customerid=@@identity"
    
            da1.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord
    
            da2.InsertCommand = da1.InsertCommand
            da2.DeleteCommand = da1.DeleteCommand
            da2.UpdateCommand = da1.UpdateCommand
    
            'Add a record to the table.
    
            Dim tblCust As DataTable
            tblCust = custDS.Tables("Customers")
    
            Dim drCust As DataRow
    
            drCust = tblCust.NewRow()
            drCust("CustomerID") = "ZYYYY"
            drCust("CompanyName") = "Zora's Yummies"
            drCust("ContactName") = "Christophe Namby"
            drCust("ContactTitle") = "Assistant Manager"
    
            tblCust.Rows.Add(drCust)
    
            'Update the backend.
    
            Debug.WriteLine("Length da1 before insert: " & da1.InsertCommand.CommandText.Length)
    
            da1.Update(custDS, "Customers")
    
            Debug.WriteLine("Length da1 after insert: " & da1.InsertCommand.CommandText.Length)
            Debug.WriteLine("length da2 before insert: " & da2.InsertCommand.CommandText.Length)
    
            da2.Update(custDS, "Customers")
    
            Debug.WriteLine("Length da2 after insert: " & da2.InsertCommand.CommandText.Length)
  5. Modificare la stringa di connessione a Microsoft SQL Server.
  6. Premere F5 per eseguire il codice.
  7. Per risolvere il problema rimuovere il commento dalla riga seguente:
            da1.Update(custDS, "Customers")
Questa soluzione funziona perché CommandBuilder aggancia l'evento RowUpdating a DataAdapter ("da1") in modo che sia possibile sapere quando generare i comandi. Quando si copiano i comandi in un DataAdapter diverso ("da2"), CommandBuilder non è più agganciato al suo evento e non li altera.

L'ambito della variabile è importante perché se "da1" e SqlCommandBuilder ("cb") fuoriescono dall'ambito e se si verifica Garbage Collection, CommandBuilder imposta i suoi comandi su Nothing (oppure null in Visual C#). Non sarà quindi possibile utilizzarli in "da2". Poiché Garbage Collection può verificarsi in qualsiasi momento, il metodo da2.Update può generare errori NullReferenceException intermittenti.

Proprietà

Identificativo articolo: 310366 - Ultima modifica: lunedì 24 febbraio 2014 - Revisione: 1.0
Le informazioni in questo articolo si applicano a
  • Microsoft ADO.NET (fornito con .NET Framework)
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
Chiavi: 
kbnosurvey kbarchive kbprb kbadonet KB310366
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com