PRB: Los comandos modificados por cambios de CommandBuilder vuelven a su estado original

Seleccione idioma Seleccione idioma
Id. de artículo: 310366 - Ver los productos a los que se aplica este artículo
Este artículo se publicó anteriormente con el número E310366
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Expandir todo | Contraer todo

En esta página

Síntomas

El objeto CommandBuilder puede volver a generar un comando que intenta modificar durante la próxima llamada al método DataAdapter.Update; en tal caso, se perderán los cambios realizados al comando. Este problema ocurre en las siguientes circunstancias:
  • Si asocia un objeto CommandBuilder con un objeto DataAdapter.
  • Si utiliza el método GetInsertCommand, GetUpdateCommand o GetDeleteCommand del objeto CommandBuilder para asignar explícitamente comandos al objeto DataAdapter.
  • Si modifica uno de los comandos generados por CommandBuilder.
Cuando intenta llamar al método Update del objeto DataAdapter, puede que aparezca el mensaje de error siguiente:
Excepción no controlada del tipo 'System.Data.SqlClient.SqlException' en system.data.dll

Causa

Este problema ocurre porque CommandBuilder modifica dinámicamente los comandos que genera y vuelve a dejar los comandos originales.

Solución

Utilice uno de los métodos siguientes para resolver este problema:
  • No modifique los comandos generados por CommandBuilder. CommandBuilder no modifica los objetos Command creados por usted.
  • Copie los objetos InsertCommand, DeleteCommand y UpdateCommand a un nuevo objeto DataAdapter (consulte la sección "Más información" para ver un ejemplo). La nueva variable DataAdapter debe tener el mismo ámbito, u otro menor, que la anterior variable DataAdapter.
  • No utilice CommandBuilder. Escriba sus propios objetos Command o utilice Visual Data Tools para escribirlos.

Estado

Este comportamiento es una característica del diseño de la aplicación.

Más información

Pasos para reproducir este comportamiento

  1. Cree un nuevo proyecto de aplicación Windows de Visual Basic. Se agregará Form1 al proyecto de manera predeterminada.
  2. Haga doble clic en el formulario y agregue el código siguiente en la parte superior de la ventana Código:
    Imports System.Data.SqlClient
  3. Agregue un control Button a Form1.
  4. Haga doble clic en el botón y agregue el código siguiente al 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")
    
            'Obtener los comandos originales.
    
            da1.InsertCommand = cb.GetInsertCommand
            da1.DeleteCommand = cb.GetDeleteCommand
            da1.UpdateCommand = cb.GetUpdateCommand
    
            Debug.WriteLine("Longitud del comando original: " & da1.InsertCommand.CommandText.Length)
    
            'Modificar el comando Insert.
    
            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
    
            'Agregar un registro a la tabla.
    
            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)
    
            'Actualizar el servidor.
    
            Debug.WriteLine("Longitud da1 antes de la inserción: " & da1.InsertCommand.CommandText.Length)
    
            da1.Update(custDS, "Customers")
    
            Debug.WriteLine("Longitud da1 después de la inserción: " & da1.InsertCommand.CommandText.Length)
            Debug.WriteLine("longitud da2 antes de la inserción: " & da2.InsertCommand.CommandText.Length)
    
            da2.Update(custDS, "Customers")
    
            Debug.WriteLine("Longitud da2 después de la inserción: " & da2.InsertCommand.CommandText.Length)
  5. Modifique la cadena de conexión para conectarse a Microsoft SQL Server.
  6. Presione la tecla F5 para ejecutar el código.
  7. Ponga como comentario la línea siguiente para resolver este problema:
            da1.Update(custDS, "Customers")
Esta solución funciona porque CommandBuilder enlaza el evento RowUpdating del DataAdapter ("da1"), por lo que sabe cuándo generar los comandos. Cuando copia los comandos a un DataAdapter diferente ("da2"), CommandBuilder ya no está enlazado a sus eventos y no los modifica.

El ámbito de la variable es importante porque si "da1" y SqlCommandBuilder ("cb") quedan fuera del ámbito, y si se recolectan los elementos no utilizados, CommandBuilder configura sus comandos como Nothing (o null en Visual C#). No puede utilizar estos comandos en "da2". Como la recolección de elementos no utilizados se produce en momentos aleatorios, la llamada al método da2.Update puede provocar errores NullReferenceException intermitentes.

Propiedades

Id. de artículo: 310366 - Última revisión: lunes, 24 de febrero de 2014 - Versión: 1.0
La información de este artículo se refiere a:
  • Microsoft ADO .NET (incluido con .NET Framework)
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
Palabras clave: 
kbnosurvey kbarchive kbprb kbadonet KB310366

Enviar comentarios

 

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