2012-04-16 19 views
9

Tengo una SqlDataSource, una Gridview y una DropDownList en la misma página. La selección DropDownList está asociada a un conjunto de SelectCommands, UpdateCommands y DeleteCommands para que pueda aprovechar el mecanismo GridView AutoGenerateEditButton = "true" y AutoGenerateUpdateButton = "true".Código SqlDataSource detrás de la orden de evento

Page_Load 
{ 
    switch(ddl.SelectedItem.Text) 
    { 
    case "A": 
     sqlDS.SelectCommand = "Select * From A"; 
     sqlDS.UpdateCommand = "Update A Set Name = @Name WHERE ID = @ID"; 
     sqlDS.DeleteCommand = "Delete A WHERE ID = @ID"; 
     break; 
    ... 
    } 

    sqlDS.DataBind(); 
    grd.DataSourceID = sqlDS.ID; 
    grd.DataBind(); 
} 

¿Cómo o en qué momento debo agregar Parámetros? ¿Es automático? Básicamente, solo quiero la capacidad de actualizar y eliminar columnas de una tabla. Quiero hacer todo esto en el archivo .cs real, en lugar de dentro del archivo .aspx, ya que me gustaría hacerlo más dinámico con el tiempo; pero por ahora solo quiero bajar lo básico. Sospecho que puedo tener la lógica DataBind() en el evento inapropiado porque no entiendo completamente el orden de los eventos asociados con el enlace de datos.

Las consultas no son complicadas y no implican uniones ni vistas; son SELECT simples sobre una sola tabla.

+0

Hay una plantilla incorporada llamada Dynamic Data que viene con ASP.Net out-of-the-box que genéricamente proporciona la capacidad de ver, actualizar, editar y eliminar registros de cualquier tabla en una fuente de datos. También puede personalizar páginas individuales, acciones individuales, tipos de campo, etc. Consulte más información aquí: http://msdn.microsoft.com/en-us/library/ee845452(v=VS.100).aspx – mellamokb

+0

¿Ha considerado? utilizando 'LinqDataSource' y LINQ-To-SQL/etc. para trabajar con tu base de datos? Puede ser mucho más fácil porque maneja la fontanería para seleccionar/insertar/actualizar automáticamente. – mellamokb

+0

Incluso si no usa datos dinámicos, puede no ser una mala idea revisar parte del código fuente de cómo funciona para obtener ideas sobre cómo simplificar su código y aprovechar las herramientas integradas para generar sentencias SQL , etc. Este tipo de cosas se han hecho muchas veces antes, y hay maneras mucho más fáciles y mucho más difíciles de hacerlo, dependiendo de cómo lo hagas. – mellamokb

Respuesta

10

Editar: Sí parece que si se utiliza AutoGenerateColumns = "true" en el GridView y rellenar a través de SqlDataSource, se unirá de forma automática los valores de los controles por su nombre a los parámetros apropiados en la consulta SQL sin ningún extra código. Sin embargo, tenemos que utilizar GetInsertCommand(true), etc, para que los comandos usan los nombres de columna (ver código de abajo donde muestro cómo utilizar SqlCommandBuilder Hay algunas trampas, sin embargo, como he descubierto en las pruebas:.

  • Es necesario configurar el DataKeyNames de su GridView
  • tendrá que establecer OldValuesParameterFormatString="Original_{0}" en sus SQLDS.
  • tendrá scb.ConflictOption = System.Data.ConflictOption.OverwriteChanges; en su SqlCommandBuilder si desea actualizar sólo que sin la comparación de los valores antiguos.
  • se aparece que si está completando Select/Update/Delet eCommand en un SqlDataSource mediante programación, debe hacerlo en cada devolución.

Sin embargo, en caso de que necesite personalizar, el control SqlDataSource proporciona los eventos Inserting, Updating, Deleting que se puede utilizar para rellenar los parámetros antes de tomar las acciones de SQL en la base de datos:

sqlDS.Updating += new SqlDataSourceCommandEventHandler(sqlDS_Updating); 

protected void sqlDS_Updating(object sender, SqlDataSourceCommandEventArgs e) 
{ 
    e.Command.Parameters["@Name"].Value = // retrieve value from user entry 
} 

El mismo tipo de cosas se puede hacer en los eventos Inserting y Deleting a través del acceso e.Command.Parameters[...].


Tenga en cuenta que también puede generar el comando/Insertar/Actualizar Borrar apropiada automáticamente utilizando la clase SqlCommandBuilder de modo que usted no tiene que construir una instrucción switch gigante que contiene todas las tablas. He aquí un ejemplo:

string tableName = ddl.SelectedValue; 
string connectionString = ConfigurationManager 
    .ConnectionStrings["MyConnectionString"].ConnectionString; 
string select = "SELECT * FROM [" + tableName + "]"; 
SqlDataAdapter sda = new SqlDataAdapter(select, connection); 
SqlCommandBuilder scb = new SqlCommandBuilder(sda); 

sqlDS.SelectCommand = select; 
sqlDS.InsertCommand = scb.GetInsertCommand(true).CommandText; 
sqlDS.UpdateCommand = scb.GetUpdateCommand(true).CommandText; 
sqlDS.DeleteCommand = scb.GetDeleteCommand(true).CommandText; 

Esto, por supuesto, requieren que todas sus tablas tienen claves primarias que se pueden utilizar para generar la actualización pertinente y eliminar declaraciones. De lo contrario, obtendrá una excepción sobre la generación de SQL dinámico. Incluso si no le gusta este método debido al costo de tiempo de ejecución de buscar el esquema en el motor de la base de datos, siempre puede pregenerarlos todos con una plantilla T4 en lugar de escribirlos todos a mano.

+1

¡Muchas gracias! La parte .GetInsertCommand (true) de un SqlCommandBuilder era lo que me faltaba. ¡Estaba generando dinámicamente una cadena en lugar de un comando! También planeo usar LinqDataSource eventualmente, pero en este momento solo una parte de mi código usa Linq; Estoy en el proceso de actualizarlo sin embargo. ¡Gracias de nuevo! – Mark

Cuestiones relacionadas