Exportar (0) Imprimir
Expandir todo

Generar comandos automáticamente

Cuando la propiedad SelectCommand se especifica de forma dinámica en tiempo de ejecución, por ejemplo a través de una herramienta de consulta que acepta un comando de texto del usuario, existe la posibilidad de que no se pueda especificar adecuadamente en tiempo de diseño si se trata de un comando InsertCommand, UpdateCommand o DeleteCommand. Si la DataTable está asignada a una única base de datos o se ha generado a partir de ella, puede utilizar el objeto DbCommandBuilder para generar automáticamente el comando DeleteCommand, InsertCommand y UpdateCommand del DbDataAdapter.

El requisito mínimo para que la generación automática de comandos funcione correctamente consiste en establecer la propiedad SelectCommand. El esquema de tabla que recupera la propiedad SelectCommand determina la sintaxis de las instrucciones INSERT, UPDATE y DELETE generadas automáticamente.

DbCommandBuilder debe ejecutar SelectCommand con el objeto de poder devolver los metadatos necesarios para construir los comandos SQL INSERT, UPDATE y DELETE. Por eso es necesario realizar un viaje adicional al origen de datos, con el consiguiente efecto adverso en el rendimiento. Para mejorar el rendimiento, debe especificar los comandos de forma explícita, en lugar de utilizar DbCommandBuilder.

SelectCommand debe además devolver al menos una clave principal o columna única. Si no hay ninguna, se inicia una excepción InvalidOperation y no se genera ningún comando.

Cuando se asocia con un DataAdapter, DbCommandBuilder genera automáticamente las propiedades InsertCommand, UpdateCommand y DeleteCommand del DataAdapter si son referencias nulas. Si ya existe algún comando Command para una propiedad, se utilizará ese.

Las vistas de bases de datos creadas al unir una o varias tablas no se consideran una tabla única de base de datos. En este caso no puede utilizar DbCommandBuilder para generar comandos automáticamente y debe especificarlos de manera explícita. Para obtener información sobre cómo especificar comandos de forma explícita para reflejar el origen de datos de las actualizaciones efectuadas en el DataSet, vea Actualizar orígenes de datos con DataAdapters.

Puede ser aconsejable asignar los parámetros de salida a la fila actualizada de un DataSet. Una tarea habitual consiste en recuperar, a partir del origen de datos, el valor de un campo de identidad de generación automática o una marca de hora. DbCommandBuilder no asigna de forma predeterminada los parámetros de salida a las columnas de una fila actualizada. En este caso, debe especificar el comando de forma explícita. Para consultar un ejemplo de asignación de un campo de identidad de generación automática a una columna de una fila insertada, vea Recuperar valores de identidad o de autonumeración.

Reglas para comandos generados automáticamente

En la tabla siguiente se muestran las reglas de la generación automática de comandos.

Comando Regla

InsertCommand

Inserta una fila en el origen de datos para todas las filas de la tabla con una RowState con el valor Added. Inserta valores para todas las columnas actualizables, pero no para determinadas columnas como identidades, expresiones o marcas de hora.

UpdateCommand

Actualiza filas en el origen de datos para todas las filas de la tabla con un valor RowState Modified. Actualiza los valores de todas las columnas, con excepción de las que no son actualizables, como identidades o expresiones. Actualiza todas las filas en las que los valores de columna en el origen de datos coinciden con los valores de la columna de clave principal de la fila, siempre que las restantes columnas del origen de datos coincidan con los valores originales de la fila. Para obtener más información, vea la sección "Modelo de simultaneidad optimista para actualizaciones y eliminaciones" de este mismo tema.

DeleteCommand

Elimina filas en el origen de datos para todas las filas de la tabla con un valor RowState Deleted. Elimina todas las filas en las que los valores de columna coinciden con los valores de la columna de clave principal de la fila, siempre que las restantes columnas del origen de datos coincidan con los valores originales de la fila. Para obtener más información, vea la sección "Modelo de simultaneidad optimista para actualizaciones y eliminaciones" de este mismo tema.

Modelo de simultaneidad optimista para actualizaciones y eliminaciones

La lógica empleada en la generación automática de comandos para las instrucciones UPDATE y DELETE se basa en la simultaneidad optimista, es decir, los registros no se bloquean para ser editados y pueden ser modificados en cualquier momento por otros usuarios o procesos. Dado que existe la posibilidad de que un registro haya sido modificado después de que haya sido devuelto por la instrucción SELECT y antes de que se emita la instrucción UPDATE o DELETE, la instrucción UPDATE o DELETE generada automáticamente incluye una cláusula WHERE que especifica que la fila sólo se actualiza cuando contiene todos los valores originales y no ha sido eliminada del origen de datos. Esto evita que se sobrescriban los datos nuevos. En los casos en que una actualización generada automáticamente intenta actualizar una fila que ha sido eliminada o que no contiene los valores originales que se encuentran en el DataSet, el comando no tienen ningún efecto en los registros y se inicia una excepción DBConcurrencyException.

Si desea que la instrucción UPDATE o DELETE se ejecute sin tener en cuenta los valores originales, debe establecer de forma explícita el UpdateCommand del DataAdapter sin utilizar la generación automática de comandos.

Limitaciones de la lógica de generación automática de comandos

La generación automática de comandos tiene las siguientes limitaciones.

Sólo tablas no relacionadas

La lógica de generación automática de comandos crea instrucciones INSERT, UPDATE o DELETE para tablas independientes sin tener en cuenta las relaciones que éstas puedan tener con otras tablas en el origen de datos. Por eso, se puede producir un error al llamar a Update para realizar cambios en una columna que participa en una restricción de clave externa en la base de datos. Para evitar esa excepción, no utilice DbCommandBuilder al actualizar las columnas que participan en una restricción de clave externa. En este caso debe especificar de forma explícita las instrucciones que se van a utilizar para llevar a cabo la operación.

Nombres de tabla y columna

La lógica de generación automática de comandos ocasiona un error cuando los nombres de las tablas o columnas incluyen algún carácter especial, como espacios, puntos, signos de exclamación y otros caracteres no alfanuméricos, aun en el caso de que se incluyan entre corchetes. Se pueden utilizar nombres completos de tabla, como catalog.schema.table.

Utilizar CommandBuilder para generar automáticamente una instrucción SQL

Para generar instrucciones SQL automáticamente para un DataAdapter, defina en primer lugar la propiedad SelectCommand del DataAdapter y, a continuación, cree un objeto CommandBuilder y especifique como argumento DataAdapter para el que CommandBuilder generará automáticamente las instrucciones SQL.

// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter adapter = new SqlDataAdapter(
  "SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";

DataSet custDS = new DataSet();

connection.Open();
adapter.Fill(custDS, "Customers");

// Code to modify data in the DataSet here.

// Without the SqlCommandBuilder, this line would fail.
adapter.Update(custDS, "Customers");
connection.Close();

Modificar SelectCommand

Es posible que se inicie una excepción si modifica el texto CommandText de SelectCommand después de generar automáticamente los comandos INSERT, UPDATE o DELETE. Si el texto de SelectCommand.CommandText modificado contiene información del esquema que sea incoherente con la del texto de SelectCommand.CommandText utilizado en el momento de la generación automática de los comandos de inserción, actualización o eliminación, las futuras llamadas al método DataAdapter.Update pueden tratar de tener acceso a columnas que ya no existan en la tabla actual a la que hace referencia SelectCommand, con lo que se inicia una excepción.

Puede actualizar la información del esquema que utiliza CommandBuilder para generar automáticamente los comandos; para ello, basta con llamar al método RefreshSchema de CommandBuilder.

Si desea conocer el comando generado automáticamente, puede obtener una referencia a los comandos generados automáticamente mediante los métodos GetInsertCommand, GetUpdateCommand y GetDeleteCommand del objeto CommandBuilder. A continuación, examine la propiedad CommandText del Command asociado.

En el ejemplo de código siguiente se escribe en la consola el comando de actualización generado automáticamente.

Console.WriteLine(builder.GetUpdateCommand().CommandText)

En el siguiente ejemplo se continúa con el código del ejemplo anterior y se recrea la tabla Customers, en la que se sustituye la columna CompanyName por la columna ContactName. Se llama al método RefreshSchema para actualizar los comandos generados automáticamente con la información de esta nueva columna.

// Assumes that connection is a valid SqlConnection object.
connection.Open();

adapter.SelectCommand.CommandText = 
  "SELECT CustomerID, ContactName FROM dbo.Customers";
builder.RefreshSchema();

custDS.Tables.Remove(custDS.Tables["Customers"]);
adapter.Fill(custDS, "Customers");

// Code to modify the new table in the DataSet here.

// Without the call to RefreshSchema, this line would fail.
adapter.Update(custDS, "Customers");

connection.Close();

Vea también

Adiciones de comunidad

AGREGAR
Mostrar:
© 2015 Microsoft