JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Usar un ObjectDataSource con un DataSet tipado en ASP.NET 2.0

El objeto ObjectDataSource que viene con ASP.NET 2.0 es estupendo ya que permite usarlo como origen de datos para enlazar rejillas y otros controles (como DetailsView por ejemplo) con objetos de negocio.

Esto va muy bien, por ejemplo, para enlazarlo con servicios Web ubicados en otras máquinas o con componentes de la capa de negocio que encapsulan las validaciones y verificaciones de seguridad aislándonos de la capa de datos (al interesado en estos temas le recomiendo el curso "Desarrollo de aplicaciones de datos en N-Capas con .NET 1.x y 2.0" de campusMVP).

Por otro lado tenemos la potencia del nuevo modelo de TableAdapters que va unido a los nuevos DataSet tipados que se crean visualmente en Visual Studio 2005. Estos enlazan los DataSet tipados con el propio acceso a datos y, en la práctica, constituyen por si mismos una verdadera capa de datos, sin necesidad de escribirla nosotros como pasaba en versiones anteriores del entorno. La verdad es que son muy potentes y encima independientes del origen de datos relacional que usemos.

Muchos programadores conocen ambas cosas y lógicamente piensan en utilizarlas conjuntamente. Es decir, crear un DataSet tipado para encapsular el acceso a datos y luego usar un ObjectDataSource para, utilizando directamente los TableAdapters, enlazar controle de la interfaz a esta capa de acceso a datos.

El caso es que esto funciona muy bien para hacer consultas y mostrar sus resultados, para eliminar registros e incluso para crear nuevos registros en la base de datos. Sin embargo en la mayor parte de los casos falla estrepitósamente al editar registros.

El motivo de esto lo encontramos en la forma (desde mi punto de vista bastante chapucera y desilusionante) en que han programado las actualizaciones en el ObjectDataSource los chicos de Microsoft. En lugar de llamar a la sobrecarga del método Update del TableAdapter que toma como parámetro un DataSet y pasarle el DataSet original obtenido en el enlace con sólo las filas modificadas (que sería en principio lo lógico y lo que se suele hacer en casi todas las aplicaciones), lo que hace este objeto es llamar a otra sobrecarga de dicho método Update que toma tantos parámetros como campos se hayan enlazado. El ObjectdataSource envía entonces los parámetros que tenga especificados en su sección <UPDATEPARAMETERS>enviándolos además en el mismo orden exactamente. Cualquier variación en el orden o el tipo hará que falle la llamada. Y lo que es peor: si en el asistente de creación del TableAdapter se marca la opción de actualziar los campos desde la base de datos (para que se traiga los autonuméricos normalmente), se añade un parámetro extra a esa sobrecarga del método Update el TableAdapter de manera que entonces el ObjectdataSource se encuentra con un parámetro de más y no sabe que hacer, generándose una excepción. Lamentable.

En las betas de .NET 2.0 pasaba esto, pero todos confiábamos en que la versión final lo tendría solucionado, cosa que no ha ocurrido. Una pena. En el curso de "Desarrollo de aplicaciones Web con ASP.NET 2.0" que estoy dando estos meses en campusMVP, y en el anteriormente mencionado sobre N-capas, esta es una de las preguntas más recurrentes que tengo por parte de los alumnos. Ahora ya sabes porqué es.

Si la parrafada anterior te ha parecido un tanto difícil de entender, simplemente haz la prueba de enlazar un GridView a un DataSet tipado con un ObjectDataSource. Edita un registro y verás exactamente a qué me refiero.

Mi consejo: el ObjectdataSource úsalo para enlazar consultas a rejillas con el ánimo de mostrar datos y navegar por ellos. Las actualizaciones a la base de datos hazlas con un componente de capa intermedia propio que utilice DataSets o bien, si no necesitas capas, usa directamente un SqlDataSource para el enlace de los datos en ambos sentidos. No te dará problemas.

José Manuel Alarcón
Banner

Comentarios (3) -

Hola Jose Manuel!!
Un comentario al respecto. Si se puede actualizar contra componentes que acepten DataTAbles ó DataRow como único parámetro de actualización, pero haciendo un truco..., con siste en que además de una lista de parámetros de campos de actualización, hay otra segunda opción que no has comentado que consiste en utilizar una única clase como parámetro del método de negocio, pero TIENE que ser una clase CUSTOM tuya, no puede ser un DataRow. Internamente dicha clase custom tiene que tener los campos con el nombre que coincida con los campos de p.e. la GRID. Una vez en la capa de componentes de negocio con el objeto de la clase custom recibibo como pa´rametro, solamente queda en ahcer una conversión a un DataRow/DataTable y llamar al método UPDATE() de ADO.NET. Un pelín trabajoso, pero queda limpio y elegante utilizando los OBJECT DATA SOURCE.

Responder

Hola César!
Ya hace unos meses que no nos vemos :-)

Lo que tú dices es correcto, pero es lioso. El objeto de mi post era explicar porqué no funcionaba el enlace directo con el DataSet tipado porque me lo preguntan constantemente en los cusos de ASP.NET y la verdad es que podían haberlo hecho mejor. Eso no significa que no haya otras formas de conseguirlo y de hehco el ObjectdataSource es super-interesante, pero eso en concreto lo podía haber solucionado mejor ¿verdad?

Un saludo

JM.

Responder

Hola José María:

Así a bote pronto, lo único que se me ocurre (ríete) es que la consulta realmente no devuelva nada. Si me dices que pones un punto de interrupción en el código de arriba, vas paso a paso y ves que, en efecto, se recogen los parámetros y se pasan correctamente al comando, y en 'n' siempre recibes 0 pero no se produce excepción alguna... entonces lo único que nos queda es que la consulta esté mal planteada o algo y por eso no devuelva valores...

Siento no poder ayudarte más.

Saludos

JM.

Responder

Agregar comentario