Cómo un control de origen de datos crea parámetros para campos enlazados a datos
Actualización: noviembre 2007
Cuando se utiliza un control enlazado a datos como GridView, DetailsView o FormView con un control de origen de datos ASP.NET, el control enlazado a datos puede pasar valores y nombres de parámetros al control de origen de datos basándose en los campos enlazados a datos del control. A continuación, el control de origen de datos incluye los nombres y los valores de los campos en la colección de parámetros para las operaciones de selección o actualización. Para obtener más información, vea Utilizar parámetros con el control SqlDataSource y Utilizar parámetros con el control ObjectDataSource.
Diccionarios pasados a los controles de origen de datos
Cuando un control enlazado a datos solicita una operación del control de origen de datos, pasa una o varias colecciones IDictionary que contienen los nombres y los valores de los parámetros para la operación de datos solicitada. Los valores de los pares de nombre y valor del diccionario se derivan de controles secundarios. Por ejemplo, en una operación de actualización, el control enlazado a datos lee los valores de los parámetros en los controles TextBox o CheckBox que se muestran en modo de edición. Los nombres de los pares de nombre y valor se toman de los nombres de los campos enlazados a los controles secundarios y de los nombres de campos especificados en la propiedad DataKeyNames. Para una operación de actualización o eliminación, el control enlazado a datos también puede pasar un diccionario que contiene los valores originales del registro de datos.
Los pares de nombre y valor se pasan mediante las colecciones IDictionary siguientes:
Colección Values Se pasa para una operación de inserción. Contiene los pares de nombre y valor para un nuevo registro. Los nombres y los valores de los campos de la colección Values se toman de los controles secundarios de una propiedad InsertItemTemplate o de los campos enlazados de un control DetailsView cuya propiedad InsertVisible está establecida en true.
Colección Keys Se pasa para las operaciones de actualización y eliminación. Contiene la clave o las claves principales del registro que se va a actualizar o eliminar. Si los campos de clave se pueden modificar en el origen de datos, la colección Keys también contiene los valores originales de dichos campos. Cuando un control enlazado a datos se rellena con datos del control de origen de datos, mantiene dichos datos en el estado de vista. Cuando se solicita una operación de actualización o eliminación, la colección Keys se rellena con los valores almacenados anteriormente en el estado de vista. Si la propiedad EnableViewState del control enlazado a datos está establecida en false, la colección Keys no se rellena para la operación de actualización o eliminación.
Colección NewValues Se pasa para una operación de actualización. Contiene los pares de nombre y valor con los nuevos valores para el elemento actualizado, incluidos los nuevos valores para los campos de clave actualizables. Los nombres y los valores de los campos de la colección NewValues se toman de los controles secundarios de una propiedad EditItemTemplate o de los campos enlazados de un control DetailsView cuya propiedad ReadOnly está establecida en false.
Colección OldValues Se pasa para las operaciones de actualización o eliminación. Contiene los valores originales del registro de datos que se van a utilizar para la comprobación de concurrencia optimista. (Para obtener información sobre la comprobación de concurrencia optimista, vea la propiedad ConflictDetection del control de origen de datos con el que está trabajando). Los valores para los campos de clave identificados por la propiedad DataKeyNames no se incluyen en la colección OldValues. Los nombres y los valores de los campos de clave sólo se incluyen en la colección Keys. Cuando un control enlazado a datos se rellena con datos del control de origen de datos, mantiene dichos datos en el estado de vista. Cuando se solicita una operación de actualización o eliminación, la colección OldValues se rellena con los valores almacenados anteriormente en el estado de vista. Si la propiedad EnableViewState del control enlazado a datos está establecida en false, la colección OldValues no se rellena para la operación de actualización o eliminación.
Para tener acceso a todas estas colecciones, puede utilizar los argumentos pasados con el evento del control enlazado a datos correspondiente a la operación solicitada. Por ejemplo, en el evento RowUpdating del control GridView, la clase GridViewUpdateEventArgs proporciona acceso a la colección NewValues.
Nombres de los parámetros
El control de origen de datos crea automáticamente parámetros para los valores pasados en las colecciones IDictionary. En una operación de inserción, el control de origen de datos rellena su colección InsertParameters con los valores de los pares de nombre y valor de la colección Values. Para una operación de actualización, el control de origen de datos rellena su colección UpdateParameters con los valores de los pares de nombre y valor de las colecciones Keys, NewValues y OldValues. En una operación de eliminación, el control de origen de datos rellena su colección DeleteParameters con los valores de los pares de nombre y valor de las colecciones Keys y OldValues.
La colección OldValues no se rellena de forma predeterminada. Sólo se rellena cuando la propiedad ConflictDetection del control de origen de datos está establecida en CompareAllValues.
Para una operación de actualización o eliminación, se crean solo parámetros para los valores de enlace actuales, de forma predeterminada. Si tiene que obtener acceso a los valores de enlace originales y actuales (por ejemplo, para admitir las comprobaciones de simultaneidad optimista), puede hacer que el control de origen de datos cree los parámetros para los valores originales y actuales. Para ello, debe establecer una convención de nomenclatura para parámetros que contendrán los valores originales. La propiedad OldValuesParameterFormatString determina el formato de los parámetros para los valores originales. Establezca la propiedad OldValuesParameterFormatString en una cadena que incluya "{0} " como marcador de posición para el nombre del campo. Por ejemplo, si utiliza el control SqlDataSource establece la propiedad OldValuesParameterFormatString en "old_{0}", los nombres de los parámetros de los valores originales se resolverán en el nombre de campo precedido por "@old_". (El control SqlDataSource anexa el carácter "@" al principio de todos los nombres de parámetro). Considere una operación de actualización que implique un campo denominado LastModifiedDate. El valor actual para el campo se pasa en el diccionario Values y el valor original para el campo, en el diccionario OldValues. Se crean un parámetro denominado @LastModifiedDate para pasar el valor actual y un parámetro denominado @old\_LastModifiedDate para pasar el valor original. Puede incluir ambos parámetros en una instrucción SQL para diferenciarlos entre los valores actuales y originales para el campo, tal como se muestra en el ejemplo siguiente:
UPDATE Table1 SET LastModifiedDate = @LastModifiedDate
WHERE Key = @Key AND LastModifiedDate = @old_LastModifiedDate
No es necesario tener acceso directo a las colecciones IDictionary de nombre y valor. Únicamente hay que incluir los nombres de parámetros generados automáticamente en las instrucciones SQL (si el origen de datos admite parámetros con nombre) o los nombres de parámetros para los métodos de datos del objeto comercial al que se va a tener acceso con un control ObjectDataSource.
También se pueden definir objetos Parameter en las colecciones UpdateParameters, InsertParameters o DeleteParameters del control de origen de datos para personalizar los valores pasados por el control enlazado a datos. Se pueden crear objetos Parameter para realizar el establecimiento inflexible de tipos del valor o para especificar un valor predeterminado si se pasa null.
En el ejemplo de código siguiente se muestra un control DetailsView enlazado a un control SqlDataSource. Las propiedades InsertCommand, UpdateCommand y DeleteCommand del control SqlDataSource utilizan los nombres de los parámetros que este control genera automáticamente. Los valores de los parámetros se rellenan en función de los diccionarios Keys y NewValues. El diccionario OldValues no se utiliza debido a que la propiedad ConflictDetection está establecida en ConflictOptions.OverwriteChanges, que es el valor predeterminado.
<%@ Page language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
Sub EmployeesDropDownList_OnSelectedIndexChanged(sender As Object, e As EventArgs)
EmployeeDetailsView.DataBind()
End Sub
Sub EmployeeDetailsView_ItemUpdated(sender As Object, e As DetailsViewUpdatedEventArgs)
EmployeesDropDownList.DataBind()
EmployeesDropDownList.SelectedValue = e.Keys("EmployeeID").ToString()
EmployeeDetailsView.DataBind()
End Sub
Sub EmployeeDetailsView_ItemDeleted(sender As Object, e As DetailsViewDeletedEventArgs)
EmployeesDropDownList.DataBind()
End Sub
Sub EmployeeDetailsSqlDataSource_OnInserted(sender As Object, e As SqlDataSourceStatusEventArgs)
Dim command As System.Data.Common.DbCommand = e.Command
EmployeesDropDownList.DataBind()
EmployeesDropDownList.SelectedValue = _
command.Parameters("@EmpID").Value.ToString()
EmployeeDetailsView.DataBind()
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" >
<h3>Northwind Employees</h3>
<table cellspacing="10">
<tr>
<td valign="top">
<asp:DropDownList ID="EmployeesDropDownList"
DataSourceID="EmployeesSqlDataSource"
DataValueField="EmployeeID"
DataTextField="FullName"
AutoPostBack="True"
OnSelectedIndexChanged="EmployeesDropDownList_OnSelectedIndexChanged"
RunAt="Server" />
</td>
<td valign="top">
<asp:DetailsView ID="EmployeeDetailsView"
DataSourceID="EmployeeDetailsSqlDataSource"
AutoGenerateRows="false"
AutoGenerateInsertbutton="true"
AutoGenerateEditbutton="true"
AutoGenerateDeletebutton="true"
DataKeyNames="EmployeeID"
Gridlines="Both"
OnItemUpdated="EmployeeDetailsView_ItemUpdated"
OnItemDeleted="EmployeeDetailsView_ItemDeleted"
RunAt="server">
<HeaderStyle backcolor="Navy"
forecolor="White"/>
<RowStyle backcolor="White"/>
<AlternatingRowStyle backcolor="LightGray"/>
<EditRowStyle backcolor="LightCyan"/>
<Fields>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
<asp:BoundField DataField="FirstName" HeaderText="First Name"/>
<asp:BoundField DataField="LastName" HeaderText="Last Name"/>
<asp:BoundField DataField="Address" HeaderText="Address"/>
<asp:BoundField DataField="City" HeaderText="City"/>
<asp:BoundField DataField="Region" HeaderText="Region"/>
<asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
</Fields>
</asp:DetailsView>
</td>
</tr>
</table>
<asp:SqlDataSource ID="EmployeesSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName AS FullName FROM Employees"
Connectionstring="<%$ ConnectionStrings:NorthwindConnection %>"
RunAt="server">
</asp:SqlDataSource>
<asp:SqlDataSource ID="EmployeeDetailsSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode
FROM Employees WHERE EmployeeID = @EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName, Address, City, Region, PostalCode)
VALUES (@LastName, @FirstName, @Address, @City, @Region, @PostalCode);
SELECT @EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName, Address=@Address,
City=@City, Region=@Region, PostalCode=@PostalCode
WHERE EmployeeID=@EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
RunAt="server">
<SelectParameters>
<asp:ControlParameter ControlID="EmployeesDropDownList" PropertyName="SelectedValue"
Name="EmpID" Type="Int32" DefaultValue="0" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="Address" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="Region" Type="String" />
<asp:Parameter Name="PostalCode" Type="String" />
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="Address" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="Region" Type="String" />
<asp:Parameter Name="PostalCode" Type="String" />
<asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
</DeleteParameters>
</asp:SqlDataSource>
</form>
</body>
</html>
<%@ Page language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
void EmployeesDropDownList_OnSelectedIndexChanged(Object sender, EventArgs e)
{
EmployeeDetailsView.DataBind();
}
void EmployeeDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e)
{
EmployeesDropDownList.DataBind();
EmployeesDropDownList.SelectedValue = e.Keys["EmployeeID"].ToString();
EmployeeDetailsView.DataBind();
}
void EmployeeDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e)
{
EmployeesDropDownList.DataBind();
}
void EmployeeDetailsSqlDataSource_OnInserted(Object sender, SqlDataSourceStatusEventArgs e)
{
System.Data.Common.DbCommand command = e.Command;
EmployeesDropDownList.DataBind();
EmployeesDropDownList.SelectedValue =
command.Parameters["@EmpID"].Value.ToString();
EmployeeDetailsView.DataBind();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" >
<h3>Northwind Employees</h3>
<table cellspacing="10">
<tr>
<td valign="top">
<asp:DropDownList ID="EmployeesDropDownList"
DataSourceID="EmployeesSqlDataSource"
DataValueField="EmployeeID"
DataTextField="FullName"
AutoPostBack="True"
OnSelectedIndexChanged="EmployeesDropDownList_OnSelectedIndexChanged"
RunAt="Server" />
</td>
<td valign="top">
<asp:DetailsView ID="EmployeeDetailsView"
DataSourceID="EmployeeDetailsSqlDataSource"
AutoGenerateRows="false"
AutoGenerateInsertbutton="true"
AutoGenerateEditbutton="true"
AutoGenerateDeletebutton="true"
DataKeyNames="EmployeeID"
Gridlines="Both"
OnItemUpdated="EmployeeDetailsView_ItemUpdated"
OnItemDeleted="EmployeeDetailsView_ItemDeleted"
RunAt="server">
<HeaderStyle backcolor="Navy"
forecolor="White"/>
<RowStyle backcolor="White"/>
<AlternatingRowStyle backcolor="LightGray"/>
<EditRowStyle backcolor="LightCyan"/>
<Fields>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
<asp:BoundField DataField="FirstName" HeaderText="First Name"/>
<asp:BoundField DataField="LastName" HeaderText="Last Name"/>
<asp:BoundField DataField="Address" HeaderText="Address"/>
<asp:BoundField DataField="City" HeaderText="City"/>
<asp:BoundField DataField="Region" HeaderText="Region"/>
<asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
</Fields>
</asp:DetailsView>
</td>
</tr>
</table>
<asp:SqlDataSource ID="EmployeesSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName AS FullName FROM Employees"
Connectionstring="<%$ ConnectionStrings:NorthwindConnection %>"
RunAt="server">
</asp:SqlDataSource>
<asp:SqlDataSource ID="EmployeeDetailsSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode
FROM Employees WHERE EmployeeID = @EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName, Address, City, Region, PostalCode)
VALUES (@LastName, @FirstName, @Address, @City, @Region, @PostalCode);
SELECT @EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName, Address=@Address,
City=@City, Region=@Region, PostalCode=@PostalCode
WHERE EmployeeID=@EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
RunAt="server">
<SelectParameters>
<asp:ControlParameter ControlID="EmployeesDropDownList" PropertyName="SelectedValue"
Name="EmpID" Type="Int32" DefaultValue="0" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="Address" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="Region" Type="String" />
<asp:Parameter Name="PostalCode" Type="String" />
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="Address" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="Region" Type="String" />
<asp:Parameter Name="PostalCode" Type="String" />
<asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
</DeleteParameters>
</asp:SqlDataSource>
</form>
</body>
</html>
Vea también
Conceptos
Utilizar parámetros con controles de origen de datos
Utilizar parámetros con el control SqlDataSource