"Nunca dejes hasta el tiempo de ejecución lo que se puede hacer en tiempo de compilación".
David Gries, Construcción de compiladores para computadoras digitales
Introducción
Como programadores, cuando aprendemos algunas tecnologías nuevas, los ejemplos a veces pueden ser nuestro mayor enemigo. Las directrices suelen estar diseñadas para ser simples y fáciles de entender, pero al mismo tiempo pueden provocar un aumento de la escritura de código perezosa, ineficiente e incluso peligrosa. La situación más común como esta se da en el paradigma ADO.NET. En este artículo, veremos lo que significa tener objetos fuertemente tipados en una base de datos, permitiéndole hacerlo en sus programas, a pesar de la falta de ejemplos.
Un poco más específicamente, veremos cómo se crean y utilizan conjuntos de datos fuertemente tipados en Visual Studio 2005. Como se explora en este artículo, los conjuntos de datos fuertemente tipados ofrecen muchas ventajas sobre otra técnica de acceso a datos débilmente tipados. También veremos aquí que crear y usar conjuntos de datos fuertemente tipados no es más fácil con Visual Studio 2005. Si quieres saber más, sigue leyendo.
Los conceptos básicos y los beneficios de los objetos fuertemente tipados
Para comprender lo que significa la tipificación fuerte, primero puede pensar en las citas. Si fueras soltero, ¿con qué tipo de persona considerarías salir? Es posible que tenga criterios específicos (como ser saludable y atractivo) o que los criterios sean simples o poco claros. No importa cuáles sean sus condiciones, cuando decida con quién pasar más tiempo, siempre utilizará sus propios estándares para que estos tipos los sopesen y consideren. Si eres inteligente, pensarás mucho para protegerte del trauma emocional. Es posible que, por ejemplo, descubra que estar con un alcohólico es inestable a menos que ambos tengan una relación seria. Sin embargo, es doloroso y muy difícil hacer que una persona cambie. Por lo tanto, tu sabiduría te indicará que detengas la relación incluso antes de que comience. Agregar una cláusula de no beber a sus criterios de citas lo protegerá de futuros dolores de cabeza y le permitirá concentrar su tiempo y energía en mejores candidatos.
Quizás se sorprenda de cómo este razonamiento tiene algo que ver con la programación. ¡No importa, ven conmigo, querido lector! Los objetos de acceso a datos de ADO.NET están diseñados para ser extremadamente flexibles. Cuando lee datos de una base de datos, probablemente esté trabajando con muchos de los tipos comunes de objetos permitidos por el marco .NET normal, a menos que encuentre problemas especiales. Al aplicar nuestra teoría de las citas, básicamente puedes pensar en tus datos relevantes como objetos universales. "Siempre y cuando mi cita no sea un problema." ¿No puedes ser más claro? ¡No hay límite incluso si se trata de un ser humano u otra criatura viviente! Como amigo tuyo, te imploro: "¡Más estándares! ¡Haz tu lista más pequeña!"
Así como descuidar con quién sales puede generar problemas en las relaciones en el futuro, dejar tus objetos sin marcar en tu código también puede causar errores. Además, si deja que objetos antiguos deambulen en su subrutina, es posible que no note que esto es un problema hasta que el programa se esté ejecutando. Para utilizar nuestra teoría de las citas, detectar errores en tiempo de ejecución es como que tu cita tenga una discusión dolorosa e incómoda en medio de un restaurante italiano de moda. Sí, verás, si hubieras planeado con anticipación, no habrías terminado con un grupo de comensales mirándote y no habría sido vergonzoso. Simplemente aplicando algunos estándares más estrictos a su código, puede detectar errores antes de que su programa comience a compilarse. Por ejemplo, el siguiente ejemplo de código:
string FirstName = myrow.("FirstName").ToString();
El DataRow en este ejemplo no tiene tipo y, como resultado, debe usar el nombre de la columna como una cadena para obtener el valor que necesita (o puede optar por usar el índice de la columna en la colección de columnas del registro). Afortunadamente esa columna existe. El tipo de datos de la columna DataRow es objeto. Suponemos que el tipo de datos en la columna FirstName es una cadena y debemos convertirlo explícitamente a una cadena antes de usarlo. Si el nombre de esta columna cambia (por ejemplo, se convierte en PersonFirstName), el compilador no tiene forma de notificárselo. ¿Deprimido? Pero no es necesario. Si su código se parece al siguiente, su vida será más sencilla y su código será más confiable.
string FirstName = PersonRow.FirstName;
en este segundo ejemplo, utilizamos una fila fuertemente tipada y sabemos que la propiedad FirstName es de tipo cadena. Sin nombres de columnas desordenados, sin conversiones de tipos desordenados. El compilador ya ha realizado la verificación de tipos por nosotros y podemos realizar otros trabajos de forma segura sin preocuparnos de si hemos escrito los nombres de las columnas correctamente.
Todo lo demás es igual, por lo que no dudarás en utilizar este en lugar del tipo genérico. Pero espera un momento, ¿de dónde vienen los objetos fuertemente tipados? También me gustaría poder decirte que estos objetos se crean automáticamente. Pero así como las buenas relaciones requieren tiempo y esfuerzo, hacer que sus objetos estén fuertemente tipados requiere un esfuerzo adicional. Pero el tiempo extra invertido aquí definitivamente vale la pena y ahorra exponencialmente más tiempo dedicado a "detectar errores" en el futuro.
Hay varias formas de lograr una escritura segura y dedicaremos el resto de este artículo a explicar cómo crear un conjunto de datos fuertemente tipado en Visual Studio 2005. También compararemos las ventajas y desventajas de este enfoque con otros enfoques.
Creación de conjuntos de datos fuertemente tipados en Visual Studio 2005
Los conjuntos de datos fuertemente tipados en realidad son solo columnas y tablas predefinidas de conjuntos de datos ordinarios, por lo que el compilador ya sabe lo que contienen. En lugar de un envoltorio suelto que le quede como un guante de béisbol, los conjuntos de datos fuertemente tipados se ajustan como un guante. Cada versión sucesiva de Visual Studio facilita el manejo de conjuntos de datos fuertemente tipados. En el siguiente ejemplo, utilizaremos la base de datos AdventureWorks de SQL Server 2005. Simplemente siga estos pasos:
1. Abra Visual Studio y cree un nuevo sitio web ASP.NET.
2. En la ventana Explorador de soluciones, haga clic derecho para agregar un nuevo elemento y seleccione Conjunto de datos. Nómbralo AdventureWorks.xsd (ver captura de pantalla). Visual Studio le recomendará que coloque el archivo DataSet en el archivo App_Code y solo tendrá que hacer clic en Aceptar.
3. Después de abrir AdventureWorks.xsd en modo de diseño, se ejecutará el asistente de configuración de TableAdapter. En este punto, haga clic en Cancelar y arrastraremos la tabla deseada desde Server Explorer.
4. Busque la base de datos AdventureWorks en la barra de herramientas del Explorador de servidores. (Si no ha instalado la base de datos AdventureWorks, puede ir a la página de descarga de Microsoft Ejemplos de SQL Server 2005 y bases de datos de muestra para descargarlo y algunos otros ejemplos de SQL Server 2005)
5. Arrastre la tabla SalesOrderHeader y la tabla SalesOrderDetail a la ventana de diseño del conjunto de datos. La ventana debería verse como en la captura de pantalla. ¿Qué estamos viendo? Cada vez que agregamos una tabla, Visual Studio creará una DataTable fuertemente tipada (con el mismo nombre que la tabla original) y un TableAdapter. Este DataTable ha definido cada columna para nosotros. TableAdapter es lo que usamos para llenar la tabla. De forma predeterminada, existe un método Fill() para obtener cada fila de datos de la tabla original.
Tal como están las cosas, este conjunto de datos fuertemente tipado devolverá todos los registros de ambas tablas. Pero la base de datos AdventureWorks contiene mucha información sobre pedidos, así que ¿por qué no crear una consulta más explícita? Podemos agregar métodos al objeto TableAdapter para obtener un conjunto de subregistros específico. Haga clic con el botón derecho en SalesORderHeaderTableAdapter y seleccione Agregar|Consulta. Seleccione "Usar declaraciones SQL" y haga clic en Siguiente, luego seleccione "SELECCIONAR que devuelve filas" y haga clic en Siguiente. Recientemente, ingrese la siguiente consulta en la ventana (o puede usar Query Builder para hacer el trabajo):
SELECCIONAR
ID de pedido de ventas, número de revisión, fecha de pedido, fecha de vencimiento, fecha de envío,
Estado, Bandera de pedido en línea, Número de pedido de ventas, Número de pedido de compra,
Número de cuenta, ID de cliente, ID de contacto, ID de persona de ventas, ID de territorio,
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID,
Código de aprobación de tarjeta de crédito, ID de tasa de moneda, subtotal, monto de impuestos, flete,
TotalDue, comentario, rowguid, fecha de modificación
DE Sales.SalesOrderHeader
DÓNDE (FechaPedido > @FechaPedido)
Esta consulta SQL es una consulta SELECT simple, que utiliza un parámetro @OrderDate para filtrar los resultados. Esto nos evitará devolver todos los registros de la base de datos. Mantenga seleccionadas las casillas de verificación "Rellenar una tabla de datos" y "Devolver una tabla de datos" y haga clic en Finalizar. Después de agregar esta instrucción SELECT, su diseñador ahora debería verse como la captura de pantalla, con una consulta adicional en SalesOrderHeaderTableAdapter.
Una vez establecido el conjunto de datos fuertemente tipados, podemos mostrar fácilmente los datos en la página ASP.NET con unas pocas líneas de código. Cree una nueva página ASP.NET en el sitio web y cambie al modo de diseño. Arrastre un control GridView sobre él y deje su ID como GirdView1. Luego vaya a la página del código fuente e introduzca el espacio de nombres AdventureWorksTableAdapters encima del archivo (la sintaxis en C# usa AdventureWorksTableAdapters;). Finalmente, agregue el siguiente código al evento Page_Load:
// Crea el SalesOrderHeaderTableAdapter
SalesOrderHeaderTableAdapter salesAdapter =
new SalesOrderHeaderTableAdapter();
// Obtener pedidos realizados después del 1 de julio de 2004
AdventureWorks.SalesOrderHeaderDataTable Órdenes =
salesAdapter.GetDataBy(new DateTime(2004, 7, 1)
// Vincula los resultados del pedido a GridView
this.GridView1.DataSource = Órdenes;
this.GridView1.DataBind();
El código es muy simple. Creamos una instancia de SalesORderHeaderTableAdapter para completar la tabla de datos. Lo que cabe señalar aquí es que, a diferencia de un DataTable normal, declaramos un objeto de tipo SalesORderHeaderDataTable. Llamamos al método GetDateBy() y pasamos un objeto DateTime para completar los datos. También tenga en cuenta aquí que el comando obtenido también está fuertemente tipado, por lo que debemos pasar un objeto DateTime en lugar de un objeto normal. La siguiente captura de pantalla es el resultado del ejemplo de código anterior.
Además de usar código para vincular el conjunto de resultados a GridView, también puede usar ObjectDataSource, establecer su propiedad TypeName en AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter y establecer su SelectMethod en GetData o GetDataBy.
Además de no tener que escribir código para conectarse a la base de datos, otra gran ventaja de usar un conjunto de datos fuertemente tipado es que no hay cadenas de nombres de columnas ocultas en nuestro código que el compilador no pueda verificar. Tampoco necesitamos realizar ninguna conversión de tipo. Si el esquema de la base de datos cambia, simplemente actualice el archivo AdventureWorks.xsd y descubriremos que todos los cambios relacionados se completan automáticamente en el momento de la compilación.
Otras técnicas para generar aplicaciones de acceso a datos fuertemente tipados
Además de utilizar conjuntos de datos fuertemente tipados, existen otras formas de implementar un tipo fuerte en sus programas. Puede crear clases personalizadas que sean más ligeras que los DataSets y más consistentes con su base de datos. También hay algunos desarrolladores de software externos que han desarrollado herramientas para automatizar este proceso. Uno de los más especiales y mi favorito es LLBLGen Pro. Una vez escribí un libro sobre él: Desarrollo rápido de Windows en C#: Visual Studio 2005, SQL Server 2005 y LLBLGen Pro. (Puede leer 1/3 del libro de forma gratuita en mi sitio web). Otra herramienta popular es CodeSmith. Incluso Microsoft está desarrollando una pequeña herramienta llamada DLINQ, pero aún se está probando y se estima que no se lance hasta al menos el próximo año.
Si utiliza el sólido enfoque de conjunto de datos de Visual Studio, una de las ventajas innegables es que no necesita comprar software adicional. Todas estas soluciones tienen diferentes características y beneficios, pero los principales beneficios son la confiabilidad, menos errores y menos tiempo dedicado a la depuración. También es más fácil comprobar el impacto de los cambios en el esquema de la base de datos y realizar el mantenimiento. Esperemos que te hayas dado cuenta de los beneficios de escribir con seguridad. ¡Buena suerte con el desarrollo (y también con las citas)!
Por Joseph Chancellor
Anexos
Descargue el código examinado en este artículo.
Sobre el autor
Joseph Chancellor es un desarrollador de C# en el sur de California que ha tenido una buena cantidad de traumas relacionales. Agradece todo tipo de comentarios y sugerencias. Visite su blog o lea los primeros cinco capítulos de su libro sobre Visual Studio 2005, SQL Server 2005 y. LLBLGen Pro
Dirección original: http://aspnet.4guysfromrolla.com/articles/020806-1.aspx.