Sunteți pe pagina 1din 54

Efectuando Acceso a Datos

Lo nuevo en 2.0
Controles de Fuente de Datos - ASP.NET 2.0 introduce controles declarativos de fuente de datos que hacen
accesibles los datos de almacenes internos (bases de datos SQL, objetos de negocios de capa intermedia o ficheros XML) a los controles de la interfaz de usuario (UI), para el enlazado a datos en una pgina. Los controles de fuente de datos tambin tienen otras capacidades como la clasificacin, la paginacin, el "catching", la actualizacin, la insercin y la eliminacin de datos, que los controles de la UI puede aprovechar sin requerir ningn tipo de cdigo.

Nuevos Controles de Enlazado a Datos - Adems de los controles de enlazado a datos de ASP.NET 1.x, ASP.NET
incluye nuevos controles de UI de enlazado a datos como el GridView, DetailsView,FormView, TreeView y Menu, que se pueden personalizar para mostrar los datos en diferentes formatos. Los controles GridView, DetailsView y FormView pueden, adems, aprovechar las capacidades de la fuente de datos, haciendo as ms sencillo las operaciones de clasificacin, paginacin y actualizacin en pginas orientadas a datos (data-driven).

Parmetros de Control de Datos - Las fuentes de datos pueden aceptar parmetros de entrada de diferentes
fuentes utilizando los nuevos "objetos de parmetros" de controles de datos de ASP.NET 2.0. Estos "objetos de parmetros" nos permiten proporcionar fcilmente los valores de las propiedades de los controles de servidor (campos sesin, aplicacin, cookie y querystring) y las propiedades del perfil de usuario para operaciones de datos parametrizadas. La utilizacin de estos parmetros permite el filtrado y escenarios de "master-details" con poco cdigo o cdigo personalizado.

Sintaxis de Enlazado a Datos Mejorada - La sintaxis de enlazado a datos de DataBinder.Eval en ASP.NET se ha


simplificado para el escenario comn de enlazar un control en una plantilla enlazada a datos. Es posible, adems, asociar dos formas de enlazar datos con las propiedades de un control en una plantilla para permitir, de esta forma, que los valores se pasen automticamente para la actualizacin, insercin o borrado en la fuente de datos. Para datos XML jerrquicos ASP.NET 2.0 tambin incluye una sintaxis de enlazado a datos basado en XPath.

Bases de Datos de Ficheros Locales Utilizando SQL Express - Para un desarrollo ms sencillo, ASP.NET 2.0 soporta
la habilidad de conectar con una base de datos SQL Express como un fichero local de la aplicacin, eliminando la necesidad de enviar la base de datos a un servidor slo para realizar el trabajo de desarrollo. Por supuesto, tambin podemos seguir conectndonos a las bases de datos de un servidor SQL. Esta seccin describe stas y otras caractersticas del acceso a datos en ASP.NET 2.0. Prcticamente todas las aplicaciones Web dinmicas realizan algun tipo de acceso a datos y, afortunadamente, ASP.NET 2.0 facilita mucho esta accin. A diferencia de ASP.NET 1.0, que requera que los desarrolladores escribieran cdigo personalizado para recuperar y enlazar los datos a controles de servidor, ASP.NET 2.0 permite una solucin declarativa para el enlazado a datos que requiere poco cdigo para los escenarios de datos ms comunes, como por ejemplo:

Seleccionar y Mostrar Datos Ordenar, Paginar y Cachear Datos Actualizar, Insertar y Borrar Datos Filtrar o "Master-Details" Utilizando Parmetros

ASP.NET 2.0 introduce dos tipos de controles de servidor que participan en este modelo declarativo de enlazado a datos. Estos dos tipos de controles de datos manejan toda la complejidad del modelo Web para escenarios de datos, de forma que los desarrolladores no tienen que entender los eventos del ciclo de vida de las peticiones para realizar el enlazado de los

datos. Otro beneficio de este modelo basado en controles es que se puede extender de forma sencilla para soportar el acceso a datos de otros proveedores.

Controles de Fuente de Datos


Los controles de fuente de datos no se representan, sino que, en lugar de eso, representan un almacn de datos, como por ejemplo una base de datos, un objeto de negocio, un fichero XML o un Web Service XML. Los controles de fuente de datos tambin hacen posibles funconalidades ms "ricas" sobre los datos (clasificacin, paginacin, filtrado, actualizacin, borrado e insercin) que pueden utilizar los controles de enlazado a datos de la UI de forma automtica. ASP.NET incluye los siguientes controles de servidor, por defecto:
Nombre SqlDataSource Descripcin Permite enlazar a una base de datos SQL representada por un proveedor ADO.NET, como por ejemplo Microsoft SQL Server, OLEDB, ODBC, o Oracle. ObjectDataSource Permite enlazar a un objeto de capa intermedia como los de capa de acceso a datos o un componente de negocios. AccessDataSource Permite enlazar a una base de datos Microsoft Access (Jet). SiteMapDataSource Permite enlazar a la jerarquia mostrada por un proveedor de navegacin de sites de ASP.NET 2.0. XmlDataSource Permite enlazar a un fichero o documento XML.

Controles de Enlazado de Datos


Los controles de enlazado de datos son controles de UI que renderizan los datos como marcas para los dispositivos o navegadores clientes. Un control de enlazado de datos puede auto-enlazar una fuente de datos a un dato mostrado y traer los datos en el momento apropiado dentro del ciclo de vida de la pgina. Estos controles puedes aprovecharse, opcionalmente, de las capacidades de la fuente de datos, como por ejemplo clasificacin, paginacin, filtrado, actualizado, borrado y insercin. Un control de enlazado de datos se conecta con una fuente de datos a travs de su propiedad DataSourceID. Podemos estar familiarizados con algunos de los controles de enlazado de datos de ASP.NET 1.x, como por ejemplo DataGrid, DataList, Repeater, y controles de lista como DropDownList. ASP.NET 2.0 contiene varios controles de enlazado de datos nuevos, como:
Nombre GridView Descripcin Presenta los datos en formato de "rejilla" (grid). Es una evolucin del control DataGrid, y puede aprovechar automticamente las caractersticas de la fuente de datos. DetailsView Presenta un slo elemento en una tabla de parejas etiqueta/valor, similar a la vista de formulario de Microsoft Access. Este control tambin puede aprovechar automticamente las caractersticas de la fuente de datos. FormView Presenta de la forma definida en una platilla personalizada un slo elemento de datos. Presenta un elemento en una tabla de parejas etiqueta/valor, similar a la vista de formulario de Microsoft Access. Este control tambin puede aprovechar automticamente las caractersticas de la fuente de datos. TreeView Presenta los datos en una vista de rbol jerrquico de nodos expandibles. Menu Presenta los datos en un men dinmico expandible (incluyendo flyouts).

Esta seccin demuestra stas y otras caractersticas nuevas de ASP.NET 2.0.

Enlazando a Bases de Datos


Uno de los tipos de datos ms comunes que se suelen representar en aplicaciones Web son datos provenientes de bases de datos SQL, como Microsoft SQL Server, Oracle, o otro almacn de datos OLEDB o ODBC. El control SqlDataSource representa una conexin directa a una base de datos en una aplicacin Web, que puede ser usada por los controles de

enlazado de datos para obtener los datos de forma automtica. Se pretende que SqlDataSource reemplace al cdigo ADO.NET que escribiriamos normalmente para crear una conexin y hacer una peticin a una base de datos. Debido a que las peticiones de datos se especificar directamente como propiedades de los controles de fuente de datos, a veces se le llama "modelo de dos capas", ya que las peticiones de datos se mantienen en el cdigo de la pgina. Por esta razn, el control SqlDataSource est dirigido hacia los sitios pequeos hechos por hobby o personales, que no requieren una encapsulacin total de los objetos de datos de nivel medio. En posteriores secciones del tutorial se hablar del control ObjectDataSource, destinado a empresas mayores, que necesitan encapsulacin de nivel medio de las peticiones a base de datos.

El Control GridView
Para demostrar como enlazar los datos desde una base de datos, los siguientes ejemplos aprovecharn el nuevo control de enlazado de datos llamado GridView. Dicho control es un nuevo control de enlazado de datos de ASP.NET 2.0 para presentar los datos en un formato de rejilla tabular. Cada fila de la rejilla corresponde a un registro de datos y las columnas representan los campos del registro. Si estis familiarizados con el control DataGrid de ASP.NET 1.x, el control GridView es el que lo reemplaza y tiene un modelo de objeto muy similar. El control GridView soporta las siguientes caractersticas:

Vicular controles de fuente a datos. Capacidades de clasificacin. Capacidades de actualizacin y borrado. Capacidades de paginacin. Capacidades de seleccin de columnas. Acceso mediante cdigo al modelo de objeto GridView para poder establecer las propiedades y manejar los eventos. Nuevos tipos de columnas como CheckBoxField y ImageField. Mltiples campos de datos para las columnas de hiperenlaces. Mltiples campos de datos llaves para seleccin, actualiacin y borrado. Apariencia personalizable a travs de temas y estilos.

Creando un Informe de Datos


El tipo ms simple que podemos encontrar en una pgina orientada a objetos es un informe de slo-lectura, que muestra los datos pero no permiten que el usuario manipule la presentacin o modifique los datos. Para crear un informe de slolectura de una base de datos SQL primero hay que configurar un SqlDataSource en la pgina y despus conectar un control enlazado a datos, como por ejemplo el GridView, a la fuente de datos, especificando la propiedad DataSourceID property. El siguiente ejemplo nos muestra un control GridView asociado a un SqlDataSource. <form runat="server"> <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" runat="server"/> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> La propiedad ConnectionString del SqlDataSource especifica la cadena de conexin a la base de datos y la propiedad SelectCommand especifica la consulta a ejecutar para obtener los datos. La cadena de conexin se puede especificar literalmente en la pgina, pero en este caso hemos asignado dicha propiedad mediante una nueva expresin que obtiene el

valor del fichero Web.config. En el siguiente ejemplo, un control GridView se enlaza a un control SqlDataSource conectado a una base de datos Microsoft SQL Server.

GridViewSimple_vb.aspx GridView-SqlDataSource
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView Bound to SqlDataSource</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" runat="server" /> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/>

</databases> </sqlCacheDependency> </caching> </system.web> </configuration>

El control SqlDataSource no se limita a conexiones con bases de datos de Microsoft SQL Server, sino que en realidad puede conectarse a cualquier proveedor ADO.NET configurado como System.Data.Common.DbProviderFactory. Por defecto, hay cuatro proveedores incluidos en el fichero machine.config del Framewrok .NET. <configuration> <system.data> <DbProviderFactories> <add name="Odbc Data Provider" invariant="System.Data.Odbc" type="System.Data.Odbc.OdbcFactory, ..." /> <add name="OleDb Data Provider" invariant="System.Data.OleDb" type="System.Data.OleDb.OleDbFactory, ..." /> <add name="OracleClient Data Provider" invariant="System.Data.OracleClient" type="System.Data.OracleClient.OracleClientFactory, ..." /> <add name="SqlClient Data Provider" invariant="System.Data.SqlClient" type="System.Data.SqlClient.SqlClientFactory, ..." /> </DbProviderFactories> </system.data> </configuration> La propiedad ProviderName de SqlDataSource se puede establecer a un nombre invariante de cualquier proveedor (por defecto System.Data.SqlClient). Observar que si cambiamos el nombre de proveedor tendremos que asegurarnos que las propiedades ConnectionString y SelectCommand utilizan la sintaxi correcta para el proveedor seleccionado. En el ejemplo anterior, el control GridView se "reflejaba contra" los campos de los registros de datos devueltos por SqlDataSource para generar dinmicamente las columnas de la rejilla. Tambin podemos especificar las columnas explcitas que queremos mostrar aadiendo objetos DataControlField a la coleccinde Columnas del GridView. Esto nos permite especificar exactamente que columnas hay que mostrar y su orden relativo. El siguiente ejemplo muestra una coleccin de objetos BoundField y CheckBoxField en la coleccin de Columnas del GridView. Otro tipo de campos que pueden ser asignados a esta coleccin son ImageField, HyperLinkField, CommandField, ButtonField y TemplateField.

GridViewBoundFields_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView Bound Fields</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" runat="server"> <Columns> <asp:BoundField HeaderText="ID" DataField="au_id" ReadOnly="true" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" /> <asp:BoundField HeaderText="Address" DataField="address" />

<asp:BoundField HeaderText="City" DataField="city" /> <asp:BoundField HeaderText="State" DataField="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" /> <asp:CheckBoxField HeaderText="Contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

La propiedad SelectCommand de SqlDataSource tambin se puede configurar con un nombre de procedimiento almacenado en lugar de un comando SQL. Para permitir esto, hay que establecer la propiedad SelectCommandType a "StoredProcedure". El siguiente ejemplo muestra el contro SqlDataSource configurado para seleccionar datos de un procedimiento almacenado en la base de datos Northwind. GridViewStoredProc_vb.aspx (BoundFields)
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView Bound to Stored Procedure</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" runat="server"> <Columns> <asp:BoundField DataField="TenMostExpensiveProducts" HeaderText="Product" /> <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="Ten Most Expensive Products" ConnectionString="<%$ ConnectionStrings:Northwind %>" SelectCommandType="StoredProcedure" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;"

providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>
La propiedad SelectCommand de SqlDataSource tambin se puede configurar con un nombre de procedimiento almacenado en lugar de un comando SQL. Para permitir esto, hay que establecer la propiedad SelectCommandType a "StoredProcedure". El siguiente ejemplo muestra el contro SqlDataSource configurado para seleccionar datos de un procedimiento almacenado en la base de datos Northwind. GridView-SqlDataSource (Procedimiento Almacenado)

GridViewStoredProc_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView Bound to Stored Procedure</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" runat="server"> <Columns> <asp:BoundField DataField="TenMostExpensiveProducts" HeaderText="Product" /> <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="Ten Most Expensive Products" ConnectionString="<%$ ConnectionStrings:Northwind %>" SelectCommandType="StoredProcedure" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration>

<connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>
Por defecto el control SqlDataSource devuelve un objeto DataView desde un objeto DataSet que contiene los resultados de la consulta. Podemos configurar el control SqlDataSource para devolver los datos como un objeto DataReader en su lugar, estableciendo la propiedad SqlDataSourceMode a "DataReader". Utilizar un DataReader es, generalmente, mejor en cuanto a rendimiento que utilizar un DataSet cuando slo necesitamos acceso read-only o "fordward-only" a los datos. Sin embargo, es importante observar que la capacidad de clasificacin del control SqlDataSource se deshabilitar en este modo. El siguiente ejemplo muestra el modo DataReades del control SqlDataSource.

GridView-SqlDataSource (DataReader)

GridViewDataReader_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView Bound to SqlDataReader</title> </head> <body> <form id="form1" runat="server">

<asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" runat="server"> <Columns> <asp:BoundField DataField="TenMostExpensiveProducts" HeaderText="Product" /> <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind %>" SelectCommand="Ten Most Expensive Products" SelectCommandType="StoredProcedure" DataSourceMode="DataReader" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching>

</system.web> </configuration>

Configuracin de Cadenas de Conexin


En los ejemplos anteriores, SqlDataSource hace referencia a la cadena de conexin a la base de datos por su nombre, utilizando la nueva sintaxis declarativa de ASP.NET 2.0 que resuelve el valor de la cadena de conexin en tiempo de ejecucin. La cadena de conexin se almacena en el fichero Web.config en la seccin de configuracin <connectionStrings>, de forma que es sencillo de mantenerlo en un solo lugar para todas las pginas de la aplicacin. <configuration> <connectionStrings> <add name="Pubs" connectionString="Server=(local);Integrated Security=True;Database=pubs;" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration> El siguiente ejemplo muestra el fichero Web.config utilizado por los anteriores ejemplos de SqlDataSource. Configuracin de Cadenas de Conexin

Web.config.strings
<?xml version="1.0"?> <configuration> <connectionStrings> <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> </system.web> </configuration>

Almacenar las cadenas de conexin en el fichero Web.config es una prctica recomendada para cualquier aplicacin ASP.NET, no slo para su administracin centralizada, sino para hacer ms seguras las cadenas de conexin. En ASP.NET 2.0 hay disponible una herramienta de linea de comandos para el encriptado de esta seccin para una mayor seguridad en ambientes de produccin. Para ms de talles sobre el encriptado de cadenas de conexin acudid a la seccin "Encriptado de Secciones de Configuracin" de la seccin de administracin de este tutorial. El siguiente ejemplo muestra el fichero Web.config con una seccin <connectionStrings/> encriptada. Configuracin de Cadenas de Conexin (Encriptadas)

Web.config.encrypted
<?xml version="1.0"?> <configuration> <protectedData> <protectedDataSections>

/>

<add name="connectionStrings" provider="RsaProtectedConfigurationProvider" inheritedByChildren="false" /> </protectedDataSections> </protectedData> <connectionStrings> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>Rsa Key</KeyName> </KeyInfo> <CipherData> <CipherValue>408EYuABn0MbVxxN9CAHMFpkX36odWkolxVw0neiuBQ888tZbpf8S7TWfp WDC4uz000uhH0FuR3iYVQkbEZ0gEU+y5zDcVp3uVzzryr7P4h/fm1oH0RnDPeKcegAkkq1HaX0tu5c5wcFm Ii2Qs4pTR8kjn30kYBfBIUg5AsdZCo=</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>5lkgSgwPTYDx6OYlRxaSLZhJwhGgssjmtljt+5Fo3hYt+Mu35oN4L4ODoiFKXp L3Kkd5+E+hABZRSJyRQPvwa26+8YGK5tV03xTjMs4rQkTh55514jv85i+bmZjNLmbw41u8QyEYEo30uu2yC hdNAjh3TEHuths9nDoqhkTzfn0sx4Hyd2xukFd037c7ZZYrTIsB+EWX9nhFXhC3tTdQrateyiOHiRgyA5tW KXea86u/IUyZhGyC2w3A/PbfJ+oAJHSRAh0YqR+mGlJDcGypwPv7laAXV0VN1H5dFzCgmF5KsUOLyBAMAk/ TGPaoXJGsdTjM2zrEzx1/8PITLU/x6IDSN2V53DRn3uHDMoHXBa6n2V3giyxpAitC/A02qDYPxuuDdPSCS7 DALh2FF4FhrcoXQVtKWq+yy3bsQG7wNbQ5b5wCopuoLnjGcPK3BAvyC43krxbyUDBzk8ZIJvo6/FDJn3Uz2 mbDquFu80yfM3YyqLV/VFuk6PXQXgF/YcbszKUiBlybSMw5KE2ieWWBiVrWExWayAGw</CipherValue> </CipherData> </EncryptedData> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> </system.web> </configuration>

La propiedad ConnectionString del control SqlDataSource se establece a la expresin <%$ ConnectionStrings:Pubs

%>, que es traducida por el analizador de ASP.NET al valor de la cadena de conexin en tiempo de ejecucin. Tambin podemos especificar una expresin para la propiedad ProviderName de SqlDataSource, por ejemplo <%$ ConnectionStrings:Pubs.ProviderName %>.

Clasificacin y Paginacin de Datos


Una de las principales ventajas del control GridView sobre otros controles de enlazado de datos es su habilidad para aprovechar las propiedades de la fuente de datos. En lugar de dejar en manos del cdigo de la pgina la clasificacin o paginacin de los datos, el control GridView puede realizar estas operaciones de forma automtica, siempre que la fuente de datos est configurada para ello. El control SqlDataSource soporta la clasificacin cuando la propiedad DataSourceMode se configura como "DataSet". Para permitir clasificacin en la UI usando un control GridView hay que configurar la propiedad AllowSorting a "verdadero". sto

provoca que el control GridView cree botones de enlazado para las cabeceras de sus columnas, en los que podamos hacer clic para clasificar la columna. El control GridView pasa la expresin SortExpression asociada con el campo de la columna al control de la fuente de datos, que devuelve los datos clasificados al GridView. La sintaxis de SortExpression que espera SqlDataSource es la misma que la de la propiedad Sort de System.Data.DataView, aunque otras fuentes de datos pueden soportar sintaxis diferentes. Debido a que el comportamiento de clasificacin de SqlDataSource depende la propiedad DataViewSort, SqlDataSource slo soporta la clasificacin en modo DataSet; si se configura como DataReader, la clasificacin se deshabilita. Normalmente asignaremos el SortExpression a un slo nombre de campo asociado con una columna del GridView. El GridView alternar de forma automtica entre "ASC" o "DESC" en SortExpression en cada clic, para conmutar entre orden de clasificacin ascendente o descendente.

Clasificacin del GridView

GridViewSorting_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Sorting Data Using GridView</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" AllowSorting="true" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="False"> <Columns> <asp:BoundField HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config

<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Tambin podemos permitir la paginacin de la UI en el control GridView, poniendo la propiedad AllowPaging a verdadero. El GridView puede paginar cualquier valor devuelto por una fuente de datos que soporte la interfaz ICollection. El DataView que devuelve SqlDataSource cuando est en en modo DataSet soporta dicha interfaz, de forma que GridView puede (paginar)"page over" el resultado. Cuando se encuentra en mode DataReader, el GridView no puede "page over" los datos devueltos por SqlDataSource. El siguiente ejemplo nos muestra la UI de paginacin del GridView con un SqlDataSource en modo DataSet.. Paginacin de GridView

GridViewPaging_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Paging Data Using GridView</title> </head> <body> <form id="form1" runat="server">

<asp:GridView ID="GridView1" AllowSorting="true" AllowPaging="true" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="False"> <Columns> <asp:BoundField HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" />

<add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Tambin podemos personalizar el estilo y la configuracin del paginador, configurando las propiedades PagerStyle y PagerSettings, respectivamente. PagerStyle determina el aspecto y la sensacin del paginador, mientras que PagerSettings determina el tipo de paginacin a usar (numrica o con botones Siguiente/anterior), la posicin del paginador y opciones relacionadas. El siguiente ejemplo muestra algunos de estos estilos y ajustes aplicados al paginador de GridView. Ajustes del Paginador de GridView

GridViewPagingSettings_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Pager Settings and Styles</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" AllowSorting="true" AllowPaging="true" PageSize="3" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="False"> <PagerSettings Mode="NextPreviousFirstLast" Position="TopAndBottom" FirstPageImageUrl="~/Images/First.gif" LastPageImageUrl="~/Images/Last.gif" NextPageImageUrl="~/Images/Next.gif" PreviousPageImageUrl="~/Images/Prev.gif" /> <PagerStyle ForeColor="White" HorizontalAlign="Right" BackColor="#284775" /> <Columns> <asp:BoundField HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" />

<asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Observar que la operacin de paginacin del anterior ejemplo la est realizando ntegramente el control GridView sobre el DataView devuelto por SqlDataSource, que soporta la interfaz ICollection. En este caso, el GridView obtiene todos los datos de la fuente de datos, presenta un subconjunto de las filas y despus descarta las restantes. A esto se le llama a veces "paginacin UI", porque la lgica de paginacin se da en la capa de presentacin del control GridView. Aunque sea conveniente para paginar colecciones arbitrarias, sta no es la forma ms eficiente de paginar los datos. tambin es posible configurar la paginacin en el nivel de la interfaz de la fuente de datos, de forma que el GridView solo pide a la fuente de datos las filas que necesita para representar la pgina. El control SqlDataSource no soporta, por ahora, paginacin a nivel de interfaz. El control ObjectDataSource no soporta esta caracterstica, y de esto se habla en el topic "Clasificacin y Paginacin Avanzadas" de este tutorial.

Actualizando y Borrando Datos


Adems de clasificacin y paginacin, el control GridView tambin permite preparar la UI para la modificacin de los datos mediante operaciones de Actualizacin y Borrado, siempre que la fuente de datos asociada se configure para soportar dichas funcionalidades. El control SqlDataSource soporta las operaciones de Actualizacin cundo se establece la propiedad UpdateCommand y las de Borrado cuando la propiedad DeleteCommand se establece a un comando vlido de actualizacin o borrado o a un procedimiento almacenado. UpdateCommand o DeleteCommand deben contener parmetros de substitucin para cada valor que pasar el control GridView (ms sobre esto abajo). Tamnbin podemos especificar una coleccin de UpdateParameters o DeleteParameters para establecer las propiedades de cada parmetro, tales como el tipo de parmetro, la direccin de entrada/salida o el valor por defecto. Se hablar ms detalladamente sobre estas colecciones en los siguientes captulos. <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [state] = @state WHERE [au_id] = @au_id" DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @au_id"/> Para permitir la Actualizacin y el Borrado desde la UI en el GridView, podemos establecer las propiedades AutoGenerateEditButton y AutoGenerateDeleteButton a verdadero, o aadir un CommandField al control GridView y habilitar sus propiedades ShowEditButton y ShowDeleteButton. El GridView soporta la edicin o borrado de una fila cada vez. Para editar, el usuario pondra la fila en modo de edicin haciendo clic sobre el botn "Edit" y despus confirmar la Actualizacin haciendo clic sobre el botn "Update" mientras la fila est en modo de edicin. El usuario tambin puede hacer clic sobre el botn "Cancel" para cancelar la operacin de edicin y volver al modo de slo-lectura. El siguiente ejemplo muestra el GridView y la SqlDataSource configurados para la actualizacin de filas de datos. Actualizacin del GridView

GridViewUpdating_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Updating Data Using GridView</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" AllowSorting="true" AllowPaging="true" Runat="server"

DataSourceID="SqlDataSource1" AutoGenerateEditButton="true" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField ReadOnly="true" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> -->

<add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Una propiedad importante que juega un papel especial en las operaciones de Actualizacin y Borrado es la propiedad de DataKeyNames. Esta propiedad se fija al valor de los nombres de los campos de la fuente de datos que forman parte de la llave primaria mediante la que podremos localizar una fila concreta en la fuente de datos. Cuando especificamos esta propiedad de forma declarativa, tendremos que separar por comas los diferentes campos, aunque normalmente se suele tener un slo campo llave. Los valores de los campos especificados en la propiedad DataKeyNames son de ida y vuelta, para poder mantener los valores originales que tendremos que pasar a las operaciones de Actualizacin y Borrado, incluso si el campo no se va a presentar como una columna en el control GridView. Cundo GridView invoca las operaciones de Actualizacin o Borrado de la fuente de datos, pasa los valores de estos campos en un diccionario de Llaves especiales, diferente al diccionario de Valores que contiene los nuevos valores que ha introducido el usuario mientras la fila estaba en modo de edicin (para operaciones de actualizacin). Los contenidos del diccionario de Valores se obtienen de los controles de entrada presentados en la fila en el modo de edicin. Para excluir un valor de este diccionario, tendremos que establecer la propiedad ReadOnly a verdadero en el correspondiente BoundField dentro del grupo de columnas. Si estamos usando el diseador de GridView de Visual Studio, la propiedad ReadOnly se pone a verdadero por defecto, para los campos de las llaves primarias. Observar la convencin en la nomenclatura de los parmetros en la sentencia de Actualizacin asignada a UpdateCommand. La capacidad automtica de invocacin la operacin de Actualizacin que tiene el GridView y otros controles de enlazado de datos depende de la convencin de la nomenclatura para su funcionamiento. Los parmetros deben ser nombrados como los valores de los campos asociados devueltos por el SelectCommand. Mediante este acuerdo en la nomenclatura se hace posible alinear los valores pasados por el control de enlazado de datos a la fuente de datos con los parmetros de la sentencia de actualizacin SQL. La utilizacin de esta convencin en la nomenclatura asume que el contenido de los diccionarios de Llaves y los de Valores son mutuamente excluyentes (es decir, los valores de los campos que deben ser actualizados por el usuario, mientras que el control de enlazado de datos est en modo de edicin, deben nombrarse de forma diferente a los valores de los campos utilizados para encontrar la fila a acualizar (en la clusula WHERE de SqlDataSource)). Otra forma de ver sto es que cualquier campo que se encuentre en DataKeyNames deber ser de slo-lectura o invisible en el control de enlace de datos (por ejemplo, en el conjunto de Columnas de GridView).

A pesar que es comn que los campos llave sean de slo-lectura, hay casos en los que querremos que se puedan actualizar campos que tambin se usan para encontrar la fila de datos a actualizar. Por ejemplo, si establecemos la propiedad ReadOnly=false en un campo del conjunto de Columnas de GridView que tambin forma parte de DataKeyNames, GridView pasar el antiguo valor al campo correspondiente del diccionario de Llaves, mientras que pasar el nuevo valor al campo del diccionario de Valores. Para diferenciar entre estos dos valores, necesitaremos nombrar los parmetros de forma diferente en la sentencia SQL, por ejemplo: <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]" UpdateCommand="UPDATE [authors] SET [au_id] = @au_id, [au_lname] = @au_lname, [au_fname] = @au_fname, [state] = @state WHERE [au_id] = @original_au_id" DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @original_au_id"/> OldValuesParameterFormatString="original_{0}" En este ejemplo, el parmetro de nombre @original_au_id se usa para hacer referencia al valor original del campo llave y @au_id para el nuevo valor. La propiedad OldValuesParameterFormatString de SqlDataSource tambin se establece a un formato de string vlido para el Framework .NET para indicar cmo deben ser renombrados los parmetros en el diccionario de Llaves. Este formato tambin se aplica a los viejos valores de los campos que no son llave que pasa el control de enlace de datos cuando la propiedad ConflictDetection de SqlDataSource se establece a CompareAllValues. En las operaciones de Borrado, SqlDataSource aplica el diccionario de Llaves por defecto (no hay nuevos valores para la operacin de borrado), usando el valor de la propiedad OldValuesParameterFormatString para dar formato a los nombres de los parmetros llave.

Filtrado de Datos
Un escenario comn en las pginas orientadas a datos es la habilidad de filtrar los datos en un informe. Por ejemplo, supongamos que un usuario pueda seleccionar entre unos valores de una DropDownList para filtrar la cuadrcula del informe de manera que slo se muestren las filas que coincidan con el valor del campo. En ASP.NET 1.x necesitbamos escribir todo este cdigo: 1. 2. 3. 4. Cancelar el enlace de datos en el Page_Load si la consulta es un postback Manejar el evento SelectedIndexChanged Aadir el SelectedValue de la DropDownList a la coleccin de Parmetros de los comandos Ejecutar el comando y llamar a DataBind

En ASP.NET 2.0 se elimina este cdigo mediante el uso de objetos Data Parameter declarativos. Un "data parameter" permite que los valores externos se asocien a operaciones de la fuente de datos de forma declarada. Estos parmetros normalmente se asocian a una variable en un comando o propiedad, por ejemplo, un parmetro de una sentecia SQL o un procedimiento almacenado para SqlDataSource. Los controles de la fuente de datos permiten acceder a las grupo de propiedades de parmetros que contienen los objetos paramtricos para cada operacin de datos soportada. Por ejemplo: <asp:DropDownList ID="DropDownList1" ... runat="server"/> ... <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE [state] = @state"> <SelectParameters> <asp:ControlParameter Name="state" ControlID="DropDownList1" PropertyName="SelectedValue" />

</SelectParameters> </asp:SqlDataSource> El siguiente ejemplo nos muestra un QueryStringUtilizado para obtener un valor paramtrico del querystring del URL de consulta: Filtrado por QueryString

GridViewQueryString_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Filtering Data In A GridView Using a QueryString</title> </head> <body> <form id="form1" runat="server"> <h4>Enter a query string on the URL, for example: GridViewQueryString_vb.aspx?state=IN</h4> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateEditButton="True" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField ReadOnly="true" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE [state] = @state" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:QueryStringParameter Name="state" QueryStringField="state" DefaultValue="CA" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" /> <asp:Parameter Name="au_fname" />

<asp:Parameter Name="phone" /> <asp:Parameter Name="address" /> <asp:Parameter Name="city" /> <asp:Parameter Name="state" /> <asp:Parameter Name="zip" /> <asp:Parameter Name="contract" /> <asp:Parameter Name="au_id" /> </UpdateParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>
El siguiente ejemplo nos muestra como un ControlParameter se usa para obtener el valor de un parmetro de un control DropDownList de la pgina: Filtrado por DropDownList

GridViewDropDownList_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Filtering Data In A GridView Using a DropDownList</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" Runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" Runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateEditButton="True" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField ReadOnly="true" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE [state] = @state" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:ControlParameter Name="state" ControlID="DropDownList1" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" /> <asp:Parameter Name="au_fname" />

<asp:Parameter Name="phone" /> <asp:Parameter Name="address" /> <asp:Parameter Name="city" /> <asp:Parameter Name="state" /> <asp:Parameter Name="zip" /> <asp:Parameter Name="contract" /> <asp:Parameter Name="au_id" /> </UpdateParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Podemos configurar los parmetros de datos para devolver valores de cualquiera de las siguientes fuentes:

Nombre Parameter

Descripcin La clase Parameter es la base comn de la que derivan el resto de tipos de Parmetros. La clase Parameter tambin siver como implementacin de parmetros estticos, dnde el valor se especifica de forma esttica mediante la propiedad DefaultValue. Parameters comparte la propiedad Namecomn, que es el nombre del parmetro para el funcionamiento de la fuente de datos (por ejemplo, esto encontrar el nombre del parmetro en el SelectCommand para SqlDataSource). Todos los parmetros comparten, tambin, la propiedad Type, que especifica cul es el tipo del valor del parmetro. Los parmetros tambin comparten la propiedad Direction, que se usa para especificar dnde usamos el parmetro como entrada, salida (o ReturnValue) o ambos, entrada y salida. Las fuentes de datos suelen mostrar los parmetros de salida y devolver valores de un evento "args" que se pasa al evento de estado de operacin de la fuente de datos. Para un ejemplo de lo aqu descrito ir a "Trabajando con Parmetros".

La clase QueryStringParameter enlaza el valor de un campo querystring al valor del objeto Parameter. La propiedad QueryStringField encuentra el nombre del campo querystring QueryStringParam desde el que se recupera el valor. La propiedad DefaultValue se devolver siempre que el eter valor querystring no est disponible. La clase ControlParameter enlaza el valor de una propiedad Control al valor de un objeto Parameter. La propiedad ControlID encuentra la ID del Control cuya propiedad est enlazada al parmetro. La PropertyName especfica la propiedad del control desde la que se obtiene el valor. El control del cul especificamos la ID mediante ControlID puede definir, opcionalmente, un ControlValuePropertyAttribute, que determina el nombre de propiedad por defecto del que obtendremos el valor del control. Esta propiedad se utilizar cuando no se establezca explcitamente el PropertyName. El ControlValuePropertyAttribute se aplica a las siguientes propiedades de control:

ControlParameter

Label.Text TextBox.Text ListControl.SelectedValue (por ejemplo, DropDownList) CheckBox.Checked Calendar.SelectedDate DetailsView.SelectedValue GridView.SelectedValue TreeView.SelectedValue FileUpload.FileBytes

La clase SessionParameter enlaza el valor de un objeto de Session con el valor de un objeto Parameter. La propiedad SessionField encuentra el nombre de la clave se Session desde la SessionParameter que se obtiene el valor. La propiedad DefaultValue se devolvera si no se puede acceder al valor de Session. La clase FormParameter vinvula el valor de un campo de un formulario HTML al valor de un objeto Parameter. La propiedad FormField encuentra el nombre del campo del formulario desde el que se obtendr el valor. La propiedad DefaultValue se devolver cuando el valor de Form no est disponible. La clase CookieParameter enlaza el valor de un HttpCookie al valor de un objeto Parameter. La propiedad CookieName encuentra el nombre de la cookie desde la que se obtendr el valor (slo se admiten cookies de valor simple "simple-valued"). La propiedad DefaultValue se devolver cuando la cookie no est disponible. La clase ProfileParameter enlaza el valor de un objeto "User Profile" al de un objeto Parameter. La propiedad ParameterName encuentra el nombre del perfil desde el que se obtendr el valor. La

FormParameter

CookieParameter

ProfileParameter

propiedad DefaultValue se devolver cuando la cookie no est disponible. Para ms informacin, acudir a la seccin "Perfiles de Usuario" del tutorial.

Observar la diferencia entre los parmetros de datos que se evaluan en una fuente interna (Control QueryString, etc.) y los que se pasan para las operaciones Actualizar, Insertar y Borrar de los ejemplos anteriores. En el ltimo escenario, los valores de los parmetros son proporcionados dinmicamente por el control de enlace de datos, en este caso GridView, qu invoca la operacin de Actualizacin. Para las operaciones de Actualizacin, Insercin y Borrado normalmente no necesitaremos parmetros de datos asciados a valores externos. Sin embargo, podemos incluir un objeto <asp:Parameter> (clase base para todos los parmetros de datos) en los grupos UpdateParameters, InsertParameters o DeleteParameters de la fuente de datos, para especificar propiedades como Type, Direction o DefaultValue(valor a usar si el que pasa GridView es null), para ser aplicadas a los valores de los parmetros pasados desde el control GridView.

Cacheando Datos
Otra caracterstica de la fuente de datos es la capacidad de chachear los datos de forma automtica. A pesar que seguimos podiendo utilizar las API's de cach para chachear los datos mediante programacin, estableciendo unas pocas caractersticas de forma declarativa en la fuente de datos podemos obtener el mismo resultado. Para permitir el cacheo para el control SqlDataSource (y ObjectDataSource, que se explica ms adelante), tendremos que fijar la propiedad EnableCaching a verdadero.Podemos especificar el tiempo (en segundos) durante el que almacenaremos una entrada en cach, mediante la propiedad CacheDuration. Tambin podemos establecer la propiedad CacheExpirationPolicy tanto a either Sliding como a Absolute, como podemos hacer desde la API de cach. El cachero slo es soportado por el control SqlDataSource cundo la propiedad DataSourceMode se fija a "DataSet". Por ejemplo, si fijamos CacheDuration a 5 y SlidingExpiration a Absolute, el SqlDataSource recuperar los datos de la base de datos en la primera peticin a la pgina, y los almacenar en la cach. Para las peticiones siguientes, la SqlDataSource intentar obtener la entrada de la cach para responder la peticin sin tener que mirar en la base de datos. Despus de 5 segundos (o quiz antes, si la presin de la memoria cach es alta), la entrada de la cach se eliminar y para la siguiente peticin el SqlDataSource tendr que volver a la base de datos de nuevo (repitiendo el proceso de cacheo para los nuevos datos). Si en lugar de eso fijamos CacheDuration a 5 y SlidingExpiration a Sliding, se refrescar el time-to-live de los datos cacheados peridicamente mientras la fuente de datos los pida al menos una vez cada 5 segundos. Si una pgina pide los datos cacheados por lo menos una vez cada 5 segundos, y no hay presin en la memoria cache, los datos cacheados se mantendrn en la cache para siempre. Por otra parte, si no se hacen peticiones de los datos cacheados en un periodo de 5 segundos, se eliminarn los datos de la cach y la prxima vez que se produzca una peticin el control SqlDataSource volver a pedir los datos a la base de datos original. El siguiente ejemplo muestra el cacheo mediante el control SqlDataSource. La columna TimeStamp se actualiza en cada peticin, de forma que podemos ver la asiduidad con la que los datos se cogen de la base de datos frente a los que se piden de la cach. Observar que aproximdamente cada 5 segundos se actualiza el TimeStamp. "Caheando" SqlDataSource

GridViewCaching_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Caching Data</title>

</head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" Runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" Runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateEditButton="True" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="TimeStamp" HeaderText="TimeStamp" ReadOnly="True"> <ItemStyle Font-Bold="True" /> </asp:BoundField> <asp:BoundField ReadOnly="True" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT DatePart(second, GetDate()) As TimeStamp, [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE [state] = @state" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>" CacheDuration="5" EnableCaching="True"> <SelectParameters> <asp:ControlParameter Name="state" ControlID="DropDownList1" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" /> <asp:Parameter Name="au_fname" />

<asp:Parameter Name="phone" /> <asp:Parameter Name="address" /> <asp:Parameter Name="city" /> <asp:Parameter Name="state" /> <asp:Parameter Name="zip" /> <asp:Parameter Name="contract" /> <asp:Parameter Name="au_id" /> </UpdateParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>
Un observador minucioso puede haberse dado cuenta que el TimeStamp tambin se actualiza cada vez que se selecciona un nuevo valor para el filtro de la DropDownlist. sto se debe a que cada conjunto de parmetros nico que se le pasa al SelectCommand tiene como resultado una peticin diferente a la base de datos y, poe consiguiente, una entrada diferente en la cach (observar que si seleccionamos el mismo valor en la DropDownList en un perodo de tiempo de 5 segundos el TimeStamp no vara).

Un enfoque alternativo, que funciona bien con peticiones de datos ms pequeos, consiste en seleccionar todos los datos de la base de datos y pasarlos a la cach, para luego filtrar esa nica entrada de la cach para los diferentes valores de los parmetros. Para soportar sto, el control SqlDataSource soporta la propiedad FilterExpression y el grupo correspondiente de FilterParameters. En lugar de aplicar los valores de los parmetros directamente sobre el comando (cmo hacamos en los SelectParameters), la expresin de filtrado se aplica sobre la propiedad RowFilter del objeto DataView devuelto por la ejecucin del comando. La sintaxis de la expresin debe encajar con la esperada para la propiedad RowFilter del DataView. Row Filter Podemos usar parmetros de substitucin para los valores de los parmetros dentro de la FilterExpression siguiendo el estndard del Framework .NET para la sintaxis de formato de strings, por ejemplo "{0}", "{1}" y sucesivamente. en tiempo de ejecucin, el control SqlDataSource aplica los valores de los parmetros especificados en el grupo FilterParameters a FilterExpression, dado formato al string con los valores. Observar que los valores de los parmetros no son "escaped", de manera que ser necesario que los pongamos entre comillas simples. <asp:DropDownList ID="DropDownList1" ... runat="server"/> ... <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]"> FilterExpression="state = '{0}'" <FilterParameters> <asp:ControlParameter Name="state" ControlID="DropDownList1" PropertyName="SelectedValue" /> </FilterParameters> </asp:SqlDataSource> El siguiente ejemplo muestra esta tcnica de filtrado en accin: Filtrando Entradas de Cach

GridViewCachingFilter_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Filtering Cached Data</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" Runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" Runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateEditButton="True" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns>

<asp:BoundField DataField="TimeStamp" HeaderText="TimeStamp" ReadOnly="True"> <ItemStyle Font-Bold="True" /> </asp:BoundField> <asp:BoundField ReadOnly="True" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT DatePart(second, GetDate()) As TimeStamp, [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>" CacheDuration="5" EnableCaching="True" FilterExpression="state='{0}'"> <UpdateParameters> <asp:Parameter Name="au_lname" /> <asp:Parameter Name="au_fname" /> <asp:Parameter Name="phone" /> <asp:Parameter Name="address" /> <asp:Parameter Name="city" /> <asp:Parameter Name="state" /> <asp:Parameter Name="zip" /> <asp:Parameter Name="contract" /> <asp:Parameter Name="au_id" /> </UpdateParameters> <FilterParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" /> </FilterParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!--

This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

El cacheo de datos debe mantener un compromiso entre rendimiento (no tenemos que volver a la base de datos en cada peticin) y los datos obsoletos (porque la entrada de cach contiene una instantnia de los datos capturados en un momento dado). Normalmente usamos valores relativamente pequeos en CacheDuration, para asegurarnos que los datos de la cach estn actualizados. Una situacin ideal consistira en invalidar la entrada de la cach nicamente cundo los datos subyacentes cambiaran. Mientras los datos no hayan cambiado, no hay ninguna razn para eliminar la entrada de la cach. Una nueva caracterstica de ASP.NET 2.0 llamada SQL Cache Invalidation, nos permite configurar la fuente de datos para cachear los datos de forma indefinida (o por una duracin especificada) hasta que los datos de la base de datos cambien, momento en el que la entrada de la cach se elimina. Esta tcnica nos permite utilizar valores mucho mayores para CacheDuration y continuar garantizando que los datos que mostramos coinciden con los valores de la base de datos. SQL Cache Invalidation slo es soportado por las bases de datos Microsoft SQL Server. Hay dos implementaciones de esta funcin: una basada en notificaciones, soportada por SQL Server 2005, y otra basada en votaciones (polling), soportada por versiones anteriores de SQL Server. La seccin de SQL Cache Invalidation nos describe los pasos necesarios para configurar ambas implementaciones. Una vez hemos configurado la SQL Cache Invalidation, podemos utilizarla desde el control de la fuente de datos, especificando la propiedad SqlCacheDependency de la fuente de datos. Si usamos la implementacin basada en

votaciones, este valor acepta un formato del tipo connectionName:tableName. Si usamos la implementacin basada en notificaciones, fijaremos la propiedad a "CommandNotification". En este ejemplo, fijamos el CacheDuration a "Infinite" y especificamos SqlCacheDependency. Observar que la columna TimeStamp no se actualiza hasta que los datos se modifican mediante el botn "Edit" del GridView. SqlCacheInvalidation de la Fuente de Datos

GridViewCachingSql_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>Data Sources and SqlCacheInvalidation</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" Runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" Runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateEditButton="True" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="TimeStamp" HeaderText="TimeStamp" ReadOnly="True"> <ItemStyle Font-Bold="True" /> </asp:BoundField> <asp:BoundField ReadOnly="True" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> </Columns> </asp:GridView>

<asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT DatePart(second, GetDate()) As TimeStamp, [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" ConnectionString="<%$ ConnectionStrings:Pubs %>" EnableCaching="True" FilterExpression="state='{0}'" SqlCacheDependency="Pubs:Authors"> <UpdateParameters> <asp:Parameter Name="au_lname" /> <asp:Parameter Name="au_fname" /> <asp:Parameter Name="phone" /> <asp:Parameter Name="address" /> <asp:Parameter Name="city" /> <asp:Parameter Name="state" /> <asp:Parameter Name="zip" /> <asp:Parameter Name="contract" /> <asp:Parameter Name="au_id" /> </UpdateParameters> <FilterParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" /> </FilterParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" />

</connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Master-Details y el Control DetailsView


En la seccin de Filtrado de Datos vimos cmo los controles de la fuente de datos pueden aceptar parmetros de fuentes externas, tales como controles de un formulario, valores de querystring, y otros. Una tcnica similar se puede emplear para crear un escenario de "master-details". Master-details se suele referir a un "convenio (Arreglo)" entre controles, en el que un registro seleccionado en un control (el control "master") muestra detalles adicionales para el registro seleccionado en otro control (el control "details"). Los detalles adicionales pueden ser propiedades del mismo elemento de datos, o registros relacionados que estn asociados al elemento de datos "master" a travs de una relacin clave externa en la base de datos. El control GridView soporta la propiedad SelectedValue, qu indica la fila que est seleccionada en el GridView. La propiedad SelectedValue evala el valor del primer campo especificado en la propiedad DataKeyNames. Podemos permitir la UI para la seleccin el el GridView fijando AutoGenerateSelectButton a verdadero, o aadiendo al grupo de columnas del GridView un CommandField con ShowSelectButton fijado a verdadero. Una vez hecho esto, la propiedad SelectedValue del GridView puede ser asociada a un ControlParameter en una fuente de datos para pedir los registros de detalles, de la misma forma que configurbamos el DropDownList en los ejemplos anteriores. Para mostrar ms detalles de la fila que est seleccionada, podemos usar otro control GridView, pero ASP.NET tambin incluye un nuevo control DetailsView que slo vale para eso. El control DetailsView presenta un solo registro cada vez, en lugar de un grupo de registros. De la misma forma que el GridView, DetailsView lo presenta en un formato tabulado, a excepcin de las filas correspondientes a cada campo de datos (como las columnas GridView). Los campos se especifican en el grupo Fields de DetailsView. Opcionalmente, el control DetailsView tambin puede paginar un grupo de registros, cmo lo hace GridView (en DetailsView, el PageSize siempre es 1). Master-Details w/ GridView and DetailsView

GridViewMasterDetails_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView DetailsView Master-Details (1 Page)</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" runat="server" />

<asp:SqlDataSource ID="SqlDataSource2" runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <table> <tr> <td valign="top"> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="au_id" AutoGenerateColumns="False" Width="427px"> <Columns> <asp:CommandField ShowSelectButton="True" /> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE ([state] = @state)" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> </td> <td valign="top"> <asp:DetailsView AutoGenerateRows="False" DataKeyNames="au_id" DataSourceID="SqlDataSource3" HeaderText="Author Details" ID="DetailsView1" runat="server" Width="275px"> <Fields> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" /> <asp:BoundField DataField="address" HeaderText="address" SortExpression="address" /> <asp:BoundField DataField="city" HeaderText="city" SortExpression="city" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:BoundField DataField="zip" HeaderText="zip" SortExpression="zip" />

<asp:CheckBoxField DataField="contract" HeaderText="contract" SortExpression="contract" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Pubs %>" ID="SqlDataSource3" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] = @au_id)"> <SelectParameters> <asp:ControlParameter ControlID="GridView1" Name="au_id" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> </td> </tr> </table> <br /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000">

<databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

DetailsView soporta la edicin, al igual que lo haca GridView, y podemos permitir la UI de la misma forma, utilizando las propiedades AutoGenerateEditButton o CommandField.ShowEditButton. Por supuesto, la fuente de datos asociada al DetailsView tiene que ser configurada para soportar la operacin de actualizacin (en este caso, especificando un UpdateCommand en SqlDataSource). El siguiente ejemplo demuestra un DetailsView configurado para soportar la edicin de registros en un escenario de master-details. Edicin de DetailsView

GridViewMasterDetailsEdit_vb.aspx
<%@ Page Language="VB" %> <html> <head id="Head1" runat="server"> <title>GridView DetailsView Master-Details (with Editing)</title> </head> <script runat="server"> Protected Sub DetailsView1_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) GridView1.DataBind() DropDownList1.DataBind() End Sub Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub GridView1_Sorted(ByVal sender As Object, ByVal a As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub GridView1_PageIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub </script> <body> <form id="form1" runat="server">

<b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" /> <asp:SqlDataSource ID="SqlDataSource2" runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <table> <tr> <td valign="top"> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="au_id" AutoGenerateColumns="False" Width="427px" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" OnSorted="GridView1_Sorted" OnPageIndexChanged="GridView1_PageIndexChanged"> <Columns> <asp:CommandField ShowSelectButton="True" /> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE ([state] = @state)" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> </td> <td valign="top"> <asp:DetailsView AutoGenerateRows="False" DataKeyNames="au_id" OnItemUpdated="DetailsView1_ItemUpdated" DataSourceID="SqlDataSource3" HeaderText="Author Details" ID="DetailsView1" runat="server" Width="275px"> <Fields> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" />

<asp:BoundField DataField="address" HeaderText="address" SortExpression="address" /> <asp:BoundField DataField="city" HeaderText="city" SortExpression="city" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:BoundField DataField="zip" HeaderText="zip" SortExpression="zip" /> <asp:CheckBoxField DataField="contract" HeaderText="contract" SortExpression="contract" /> <asp:CommandField ShowEditButton="True" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="< %$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] = @au_id)" UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id"> <SelectParameters> <asp:ControlParameter ControlID="GridView1" Name="au_id" PropertyName="SelectedValue" Type="String" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" Type="String" /> <asp:Parameter Name="au_fname" Type="String" /> <asp:Parameter Name="phone" Type="String" /> <asp:Parameter Name="address" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="state" Type="String" /> <asp:Parameter Name="zip" Type="String" /> <asp:Parameter Name="contract" Type="Boolean" /> <asp:Parameter Name="au_id" Type="String" /> </UpdateParameters> </asp:SqlDataSource> </td> </tr> </table> <br /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally

<add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Normalmente los controles de enlazado de datos re-enlazan de forma automtica la fuente de datos cuando cambia la fuente de datos (por ejemplo, despus de una actualizacin). Sin embargo, en el ejemplo anterior, el DetailsView se enlaza a una fuente de datos diferente a la del GridView, de forma que cuando se invoca la operacin de actualizacin, solo el DetailsView recive el evento de cambio de su fuente de datos. Para forzar que el GridView tambin re-enlace cundo el DetailsView realiza una actualizacin, podemos llamar explcitamente al DataBind() del GridView en el evento

ItemUpdated del DetailsView. Este ejemplo tambin maneja eventos para no permitir la edicin cundo una operacin
de clasificacin o paginacin del gridView ocurre al mismo tiempo que se selecciona un valor de filtrado en el control DropDownList. Tambin es comn el dividir la visualizacin del master-details a travs de varias pginas de una aplicacin Web. Para hacer sto podemos aadir un hipervnculo a cada fila del GridView para navegar a diferentes pginas de detalles, pasando argumentos mediante el querystring. En la pgina de detalles, la fuente de datos enlazada al DetailsView aceptar estos argumentos mediante un objeto QueryStringParameter. Un hipervnculo deber ser aadido al GridView aadiendo un objeto HyperLinkField al grupo de Columnas de GridView. La propiedad Text del HyperLinkField fija el texto a mostrar en el hipervnculo (por ejemplo "View Details..."), mientras que la propiedad NavigateUrl especifica la URL dnde navegaremos al hacer clic sobre el enlace. En lugar de especificar una URL esttica para todas las filas, es ms comn especificar NavigateUrlFields para ser usado en la construccin de una URL dinmica. Se puede fijar NavigateUrlFields de forma declarativa a un conjunto de campos separados por comas, de la fuente de datos. La propiedad NavigateUrlFormatString especifica el formato del estndard del Framework .NET para la

URL, mediante parmetros de substicutcin cmo {0} y {1} para substituis los valores del campo, en tiempo de ejecucin. Este ejemplo muestra un escenario master-details utilizando GridVIew y DetailsVIew en pginas separadas. A diferencia de los ejemplos anteriores, qu mostraban el GridView y el DetailsView enlaados a el mismo tipo de registro (un "author"), este ejemplo muestra diferentes tipos de registros para los controles "master" y "details" ("author" y "books"), saociados por relaciones clave externas en la base de datos. Debido a que un registro de un autor puede tener ms de un libro asociado, se ha configurado el DetailsView para soportar paginacin en los registros de libros, en la pgina de detalles. Master-Details (Pginas Separadas)

GridViewMasterDetailsPage_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>GridView DetailsView Master-Details (2 Page)</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" Runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" Runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" Runat="server" DataSourceID="SqlDataSource1" DataKeyNames="au_id" AutoGenerateColumns="False"> <Columns> <asp:BoundField ReadOnly="true" HeaderText="ID" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" /> <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" /> <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" /> <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" /> <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" /> <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" /> <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" /> <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" /> <asp:HyperLinkField HeaderText="View Details..." Text="View Details..." DataNavigateUrlFields="au_id" DataNavigateUrlFormatString="DetailsView_vb.aspx?ID={0}" /> </Columns> </asp:GridView>

<asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE [state] = @state" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:ControlParameter Name="state" ControlID="DropDownList1" /> </SelectParameters> </asp:SqlDataSource> </form> </body> </html>

DetailsView_vb.aspx
<%@ Page Language="VB" %> <html> <head runat="server"> <title>DetailsView</title> </head> <body> <form id="form1" runat="server"> <asp:DetailsView ID="DetailsView1" Runat="server" DataSourceID="SqlDataSource1" AutoGenerateRows="False" HeaderText="Books for Author" AllowPaging="True"> <Fields> <asp:BoundField HeaderText="au_id" DataField="au_id" SortExpression="au_id" /> <asp:BoundField HeaderText="title_id" DataField="title_id" SortExpression="title_id" /> <asp:BoundField HeaderText="title" DataField="title" SortExpression="title" /> <asp:BoundField HeaderText="type" DataField="type" SortExpression="type" /> <asp:BoundField HeaderText="price" DataField="price" SortExpression="price" /> <asp:BoundField HeaderText="notes" DataField="notes" SortExpression="notes" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT dbo.authors.au_id, dbo.titles.title_id, dbo.titles.title, dbo.titles.type, dbo.titles.price, dbo.titles.notes FROM dbo.authors INNER JOIN dbo.titleauthor ON dbo.authors.au_id = dbo.titleauthor.au_id INNER JOIN dbo.titles ON dbo.titleauthor.title_id = dbo.titles.title_id WHERE (dbo.authors.au_id = @au_id)" ConnectionString="<%$ ConnectionStrings:Pubs %>"> <SelectParameters> <asp:QueryStringParameter Name="au_id" DefaultValue="213-46-8915" QueryStringField="ID" /> </SelectParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Insertando Datos
Al igual que el control GridView, el control DetailsView soporta la Actualizacin y el Borrado de datos en su fuente de datos. Sin embargo, DetailsView tambin soporta la insercin de datos, cosa que no haca GridView. Podemos emparejar de forma sencilla un DetailsView con un GridView para permitir que se vean los registros de insercin en el GridView. Para permitir que la SqlDataSource soporte Inserciones, tenemos que fijar la propiedad InsertCommand a un comando vlido de insercin, con parmetros de substitucin para el valor de cada campo que es representado por el DetailsView en el modo de Insercin. Tambin podemos, de forma opcional, especificar un grupo de InsertParameters que contengan los objetos de parmetros de datos para esta operacin. Para permitir la insercin en la UI, hay que fijar la propiedad AutoGenerateInsertButton a verdadero o aadir al grupo de

campos de DetailsView un CommandField con ShowInsertButton establecido a verdadero. Para pasar el DetailsView a modo de insercin, tenemos que hacer clic en el botn clic. DetailsView representar controles de entrada para cada campo cundo estemos en el modo de insercin. Observar que los campos marcados como "ReadOnly" se representan como controles de entrada en el modo de Insercin (a pesar que no lo haran en modo Actualizacin). Para excluir un campo en el modo de Insercin, tendremos que establecer la propiedad InsertVisible del campo a falso. Para realizar la operacin de Insercin, hay que hacer clic en el botn "Insert" mientras estamos en el modo de insercin. Para abortar la insercin, hacer clic en el botn "Cancel". Cuando se ha llevado a cabo una operacin de insercin, el DetailsView recoge los valores de sus entradas y llena un diccionario de Valores que se pasar a la fuente de datos. El SqlDataSource aplica estos valores al grupo de parmetros de InsertCommand antes de ejecutar el comando. De la misma forma que con las Actualizaciones, la capacidad de insercin automtica recae en parmetros en el InserCommand, que se llamn exactamente de la misma forma que los campos que se devuelven en la operacin de seleccin. Observar que el diccionario de Claves no se requiere para la insercin. Insercin en Master-Details

GridViewMasterDetailsInsert_vb.aspx
<%@ Page Language="VB" %> <script runat="server"> Protected Sub DetailsView1_ItemInserted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertedEventArgs) If (Not e.Exception Is Nothing) Then ErrorMessageLabel.Text = "An error occured while entering this record. Please verify you have entered data in the correct format." e.ExceptionHandled = True End If GridView1.DataBind() End Sub Protected Sub DetailsView1_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) GridView1.DataBind() End Sub Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub GridView1_PageIndexChanged(ByVal sender As Object, ByVal e As EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly)

End Sub Protected Sub GridView1_Sorted(ByVal sender As Object, ByVal e As System.EventArgs) DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) End Sub Protected Sub GridView1_RowDeleted(ByVal sender As Object, ByVal e As GridViewDeletedEventArgs) If (Not e.Exception Is Nothing) Then ErrorMessageLabel.Text = "Failed to DELETE due to foreign key contstraint on the table. You may only delete rows which have no related records." e.ExceptionHandled = True End If End Sub Protected Sub DetailsView1_DataBound(ByVal sender As Object, ByVal e As EventArgs) If (DetailsView1.CurrentMode = DetailsViewMode.Insert) Then Dim stateTextBox As TextBox = CType(DetailsView1.Rows(6).Cells(1).Controls(0), TextBox) stateTextBox.Text = DropDownList1.SelectedValue stateTextBox.Enabled = False End If End Sub </script> <html> <head id="Head1" runat="server"> <title>GridView DetailsView Master-Details (Insert)</title> </head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" /> <asp:SqlDataSource ID="SqlDataSource2" runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <table> <tr> <td valign="top"> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="au_id" AutoGenerateColumns="False" Width="500px" SelectedIndex="0" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" OnPageIndexChanged="GridView1_PageIndexChanged" OnRowDeleted="GridView1_RowDeleted" OnSorted="GridView1_Sorted">

<Columns> <asp:CommandField ShowSelectButton="true" ShowDeleteButton="true" /> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="< %$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE ([state] = @state)" DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @au_id"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> </td> <td valign="top"> <asp:DetailsView AutoGenerateRows="False" DataKeyNames="au_id" DataSourceID="SqlDataSource3" HeaderText="Author Details" ID="DetailsView1" runat="server" Width="275px" OnItemUpdated="DetailsView1_ItemUpdated" OnItemInserted="DetailsView1_ItemInserted" OnDataBound="DetailsView1_DataBound"> <Fields> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" /> <asp:BoundField DataField="address" HeaderText="address" SortExpression="address" /> <asp:BoundField DataField="city" HeaderText="city" SortExpression="city" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:BoundField DataField="zip" HeaderText="zip" SortExpression="zip" /> <asp:CheckBoxField DataField="contract" HeaderText="contract" SortExpression="contract" /> <asp:CommandField ShowEditButton="True" ShowInsertButton="True" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="< %$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] = @au_id)"

UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id" InsertCommand="INSERT INTO [authors] ([au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract]) VALUES (@au_id, @au_lname, @au_fname, @phone, @address, @city, @state, @zip, @contract)"> <SelectParameters> <asp:ControlParameter ControlID="GridView1" Name="au_id" PropertyName="SelectedValue" Type="String" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" Type="String" /> <asp:Parameter Name="au_fname" Type="String" /> <asp:Parameter Name="phone" Type="String" /> <asp:Parameter Name="address" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="state" Type="String" /> <asp:Parameter Name="zip" Type="String" /> <asp:Parameter Name="contract" Type="Boolean" /> <asp:Parameter Name="au_id" Type="String" /> </UpdateParameters> <InsertParameters> <asp:Parameter Name="au_id" Type="String" /> <asp:Parameter Name="au_lname" Type="String" /> <asp:Parameter Name="au_fname" Type="String" /> <asp:Parameter Name="phone" Type="String" /> <asp:Parameter Name="address" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="state" Type="String" /> <asp:Parameter Name="zip" Type="String" /> <asp:Parameter Name="contract" Type="Boolean" /> </InsertParameters> </asp:SqlDataSource> </td> </tr> </table> <br /> <asp:Label ID="ErrorMessageLabel" EnableViewState="false" runat="server" /> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" />

<add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Podemos situar el DetailsView en una pgina separada para realizar las operaciones de Insercin o Actualizacin. El siguiente ejemplo muestra un DetailsView configurado en una pgina separada para realizar las Inserciones y Actualizaciones. Observar que la propiedad DefaultMode se ha fijado en el ejemplo a Insert o Edit, de forma que DetailsView se representar inicialmente en este modo, en lugar de el modo slo-lectura. Despus de una Insercin o una Actualizacin, DetailsView siempre vuelve al DefaultMode (por defecto ReadOnly). Insercin en Master-Details (Pginas Separadas)

GridViewMasterDetailsInsertPage_vb.aspx
<%@ Page Language="VB" %> <script runat="server"> Protected Sub GridView1_RowDeleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeletedEventArgs) If (Not e.Exception Is Nothing) Then ErrorMessageLabel.Text = "Failed to DELETE due to foreign key contstraint on the table. You may only delete rows which have no related records." e.ExceptionHandled = True End If End Sub </script> <html> <head runat="server"> <title>GridView DetailsView Master-Details (Edit and Insert Pages)</title>

</head> <body> <form id="form1" runat="server"> <b>Choose a state:</b> <asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2" AutoPostBack="true" DataTextField="state" runat="server" /> <asp:SqlDataSource ID="SqlDataSource2" runat="server" SelectCommand="SELECT DISTINCT [state] FROM [authors]" ConnectionString="<%$ ConnectionStrings:Pubs %>" /> <br /> <br /> <asp:GridView ID="GridView1" AllowSorting="True" AllowPaging="True" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="au_id" AutoGenerateColumns="False" Width="500px" OnRowDeleted="GridView1_RowDeleted"> <Columns> <asp:CommandField ShowDeleteButton="True" /> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:HyperLinkField HeaderText="Edit..." Text="Edit..." DataNavigateUrlFields="au_id" DataNavigateUrlFormatString="DetailsViewEdit_vb.aspx?ID={0}" /> </Columns> </asp:GridView> <br /> <asp:HyperLink ID="HyperLink1" Text="Add New Author..." NavigateUrl="DetailsViewInsert_vb.aspx" runat="server" /> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors] WHERE ([state] = @state)" DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @au_id"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="state" PropertyName="SelectedValue" Type="String" /> </SelectParameters> <DeleteParameters> <asp:Parameter Name="au_id" Type="String" /> </DeleteParameters> </asp:SqlDataSource> <br /> <br /> <asp:Label ID="ErrorMessageLabel" EnableViewState="false" runat="server" /> </form> </body> </html>

DetailsViewEdit_vb.aspx
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub DetailsView1_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Response.Redirect("GridViewMasterDetailsInsertPage_vb.aspx") End Sub Protected Sub DetailsView1_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) If (e.CancelingEdit = True) Then Response.Redirect("GridViewMasterDetailsInsertPage_vb.aspx") End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>DetailsView Edit</title> </head> <body> <form id="form1" runat="server"> <asp:DetailsView DefaultMode="Edit" AutoGenerateRows="False" DataKeyNames="au_id" DataSourceID="SqlDataSource3" HeaderText="Edit Author" ID="DetailsView1" runat="server" Width="275px" OnItemUpdated="DetailsView1_ItemUpdated" OnModeChanging="DetailsView1_ModeChanging"> <Fields> <asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" /> <asp:BoundField DataField="address" HeaderText="address" SortExpression="address" /> <asp:BoundField DataField="city" HeaderText="city" SortExpression="city" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:BoundField DataField="zip" HeaderText="zip" SortExpression="zip" /> <asp:CheckBoxField DataField="contract" HeaderText="contract" SortExpression="contract" /> <asp:CommandField ShowEditButton="True" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] = @au_id)"

UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id"> <SelectParameters> <asp:QueryStringParameter Name="au_id" QueryStringField="ID" Type="String" /> </SelectParameters> <UpdateParameters> <asp:Parameter Name="au_lname" Type="String" /> <asp:Parameter Name="au_fname" Type="String" /> <asp:Parameter Name="phone" Type="String" /> <asp:Parameter Name="address" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="state" Type="String" /> <asp:Parameter Name="zip" Type="String" /> <asp:Parameter Name="contract" Type="Boolean" /> <asp:Parameter Name="au_id" Type="String" /> </UpdateParameters> </asp:SqlDataSource> </form> </body> </html>

DetailsViewInsert_vb.aspx
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub DetailsView1_ItemInserted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertedEventArgs) Response.Redirect("GridViewMasterDetailsInsertPage_vb.aspx") End Sub Protected Sub DetailsView1_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) If (e.CancelingEdit = True) Then Response.Redirect("GridViewMasterDetailsInsertPage_vb.aspx") End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>DetailsView Insert</title> </head> <body> <form id="form1" runat="server"> <asp:DetailsView DefaultMode="Insert" AutoGenerateRows="False" DataKeyNames="au_id" DataSourceID="SqlDataSource3" HeaderText="Insert Author" ID="DetailsView1" runat="server" Width="275px" OnItemInserted="DetailsView1_ItemInserted" OnModeChanging="DetailsView1_ModeChanging"> <Fields>

<asp:BoundField DataField="au_id" HeaderText="au_id" ReadOnly="True" SortExpression="au_id" /> <asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" /> <asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" /> <asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" /> <asp:BoundField DataField="address" HeaderText="address" SortExpression="address" /> <asp:BoundField DataField="city" HeaderText="city" SortExpression="city" /> <asp:BoundField DataField="state" HeaderText="state" SortExpression="state" /> <asp:BoundField DataField="zip" HeaderText="zip" SortExpression="zip" /> <asp:CheckBoxField DataField="contract" HeaderText="contract" SortExpression="contract" /> <asp:CommandField ShowInsertButton="True" /> </Fields> </asp:DetailsView> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] = @au_id)" InsertCommand="INSERT INTO [authors] ([au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract]) VALUES (@au_id, @au_lname, @au_fname, @phone, @address, @city, @state, @zip, @contract)"> <SelectParameters> <asp:QueryStringParameter Name="au_id" QueryStringField="ID" Type="String" /> </SelectParameters> <InsertParameters> <asp:Parameter Name="au_id" Type="String" /> <asp:Parameter Name="au_lname" Type="String" /> <asp:Parameter Name="au_fname" Type="String" /> <asp:Parameter Name="phone" Type="String" /> <asp:Parameter Name="address" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="state" Type="String" /> <asp:Parameter Name="zip" Type="String" /> <asp:Parameter Name="contract" Type="Boolean" /> </InsertParameters> </asp:SqlDataSource> </form> </body> </html>

Web.config
<?xml version="1.0"?> <configuration> <connectionStrings> <!-This connection is inherited from the ASP.NET Quickstart Web.config file Uncomment this section to edit the sample locally

<add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True" providerName="System.Data.SqlClient" /> <add name="Contacts" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Contacts;Persist Security Info=True" providerName="System.Data.SqlClient" /> --> <add name="NorthwindOLEDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory| Northwind.mdb;" providerName="System.Data.OleDb" /> <add name="ContactsDatabase" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=true;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <pages styleSheetTheme="Default"/> <caching> <sqlCacheDependency enabled="true" pollTime="1000"> <databases> <add name="Pubs" connectionStringName="Pubs"/> </databases> </sqlCacheDependency> </caching> </system.web> </configuration>

Web.config

S-ar putea să vă placă și