127.0.0.1: Hogar dulce hogar

jueves, 29 de julio de 2010

[ADO.NET] Obtener datos con DataSet

Siguiendo con la línea de artículos de la parte de acceso a datos del .NET Framework, en el presente mostraré cómo se pueden obtener datos y trabajar con ellos a través de un DataSet. Nuestro objetivo primero será obtener los datos de los jugadores de todos los equipos. Para ello emplearemos un SqlDataAdapter a través del cual ejecutaremos la consulta SQL que deseemos y posteriormente con los datos obtenidos, rellenaremos un DataSet:

   1: DataSet jugadores = new DataSet();
   2:  
   3:             try
   4:             {
   5:                 Conexion.AbreConexion();
   6:                 SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from Jugador", Conexion.Instancia);
   7:  
   8:                 dataAdapter.Fill(jugadores);
   9:                 jugadores.Tables[0].TableName = "Jugador";
  10:  
  11:             }

Una vez hemos rellenado nuestro DataSet, podemos ajustar varios parámetros, entre ellos el nombre de la tabla. Esto es importante porque podemos montar en un mismo DataSet varias tablas y relacionarlas entre ellas, por lo que es conveniente ajustar el nombre de las mismas de un modo que el programador les resulte familiar y sea acorde a la representación de datos con la que trabaja. En nuestro caso y al tener una única tabla, le asignaremos el nombre de “Jugador”.

Al ejecutar esta función, devolveremos el DataSet resultante de la consulta. ¿Y esto como se puede manejar en la interfaz? Usaremos la herramienta DataGridView:

image

Este control permite representar una tabla de filas y columnas. Se puede enlazar directamente con DataSets que podemos crear a través de un asistente al que podemos acceder a través del propio DataGridView cuando lo insertamos en una ventana:

image

En nuestro caso como ya tenemos el código que nos va a devolver el DataSet, nos olvidamos del asistente y creamos un objeto DataSet en la ventana que permita trabajar en modo desconectado con los datos proporcionados. Añadimos un botón para invocar a la función anterior y asignar el DataSet cargado a nuestro DataGridView:

   1: dataset = CAD.Equipo.ObtenerJugadores();
   2: dataGridView1.DataSource = dataset.Tables[0];

En este punto es importante recordar que DataSet no es una tabla ni una consulta, es una representación del estado de los datos obtenidos en su conjunto, por lo que debemos especificar qué tabla queremos mostrar. En este caso mostramos la primera tabla (puesto que tiene el índice 0) pero también hubiéramos podido obtener la tabla a través de su propio nombre:

   1: dataset = CAD.Equipo.ObtenerJugadores("fcb");
   2: dataGridView1.DataSource = dataset.Tables["Jugador"];

A partir de ejecutar dicho código, en nuestro DataGridView obtendremos exactamente las mismas columnas que tenemos en la tabla de Jugador en la BD. Todo esto se puede especificar, bien a través de la obtención de los datos o bien a través de personificar el DataGridView para que muestra sólo aquellas columnas que se requieran.

miércoles, 28 de julio de 2010

[VS2010] Call Hierarchy

En estos días estoy actualizándome un poco y pasando a Visual Studio 2010. De todas las novedades que incluye además del apartado visual hay dos que me han llamado la atención, siendo una de ellas la herramienta Call Hiearchy.

Esta herramienta nos proporciona como su propio nombre indica la secuencia de llamadas de una propiedad o método de una clase. Veamos un ejemplo:

Vamos a analizar qué llamadas se realizan al método AbreConexión y qué llamadas se realizan desde dicho método hacia otros objetos. Para ello, abrimos la clase Conexion y nos situamos sobre el método que queremos analizar. Pulsamos el botón derecho sobre su nombre de modo que nos aparezca el siguiente menú contextual:

image

Nos desplazamos hacia la opción de View Call Hiearchy y se abrirá la siguiente ventana:

image

Como se aprecia está distribuida en dos zonas. En primer lugar a la izquierda aparecen las llamadas y a la derecha las secciones de código dentro de cada método seleccionado a la izquierda donde aparece la referencia a nuestro método/propiedad a analizar. Si hacemos doble clic sobre cualquier elemento, nos llevará automáticamente al código referenciado y si hacemos clic con el botón derecho, aparece lo siguiente:

image

Con Go To Definition se aplica lo que mencioné en el anterior párrafo. Con Find All References el IDE busca todas las referencias a ese método/propiedad. Si por el contrario seleccionamos Add as New Root podremos añadir a la lista de jerarquías dicho método/propiedad a analizar. En la imagen de ejemplo, he decidido analizar las llamadas en las que interactúa el método AltaEquipo y como se parecia, aparece como una nueva raíz.

Por último, sólo me falta resaltar que es una novedad muy interesante, ya que para aquellas situaciones en las que se deba realizar un análisis del código o de una determinada función, permitirá ayudar bastante y tener todo de un modo más ordenado.

viernes, 16 de julio de 2010

[ADO.NET] DataSet

Siguiendo con el taller de ADO, ahora vamos a aplicar el potencia de una de las herramientas más importantes de la versión 2.0 de .NET Framework: El dataset.

Hasta ahora hemos estado viendo cómo acceder a los datos a través de entidades que permiten que permiten aplicar casi directamente los comandos de SQL sobre la base de datos. La opción propuesta por Microsoft desde .NET Framework como alternativa es el DataSet, que nos aporta las siguientes características:

Está diseñado para el acceso a datos independientemente del origen de datos e incluso se puede emplear con distintos orígenes al mismo tiempo. Además, es totalmente serializable con XML, lo que permite que esa muy apto para comunicar nuestro sistema con entidades externas.

Internamente el DataSet se componen de una colección de DataTable, formados por filas y columnas de datos junto con información propia de la tabla (identificador, nombre, claves principales, claves ajenas, etc)

En el diagrama siguiente se ilustra la relación entre un proveedor de datos de .NET Framework y un DataSet.

image

Y a continuación se muestra el modelo de datos del DataSet:

image

  • DataRelationCollection: Una colección de relaciones representadas por la entidad DataRelation. Enlaza una DataTable con otra a través de sus relaciones como si fuera una base de datos relacional. Estas relaciones pueden se pueden modificar y alterar en función de nuestras necesidades.
  • DataTableCollection: Una colección de DataTables. Cada tala tiene sus columnas ( DataColumnCollection), filas ( DataRowColletion ), restricciones ( Constraints ). Es de señalar algo muy importante que ocurre con las DataRow, que almacenan el estado original y actual de modo que puede detectar cambios en los valores almacenados.
  • ExtendedProperties: Como se apreciamos en el modelo de datos este componente se repite varias veces. ExtendedProperties no es más que un PropertyCollection en la que podemos colocar información personalizada, como por ejemplo la instrucción select que empleamos para generar los datos, la hora en que se generaron, etc.

En los próximos artículos pondré ejemplos de cómo trabajar con DataSets.

[eMeS] Mecánicas de Iredia: The Atram’s Secret

Hace poco publicamos un video mostrando algunas de las mecánicas, que tengo el placer de enlazar:

Como siempre, el juego está ahora mismo en playtest y hay multitud de pequeñas cosas que se están depurando para que dentro de poco, muy poco se pueda desargar del bazar de XBOX Live.

Ya veo la luz, y quién me diría a mí que podría trabajar en un videojuego y publicarlo para XBOX360 hace 3 años…

miércoles, 30 de junio de 2010

[ADO.NET] Hacer un Insert y no morir en el intento

Después de hacer una lectura de una base de datos, ¿qué mejor que hacer un Insert para demostrar nuestro poderoso dominio con la información? ADO.NET ofrece unas cuantas soluciones, de las cuales veremos una: empleando un SqlCommand.

Todos conocemos la instrucción Insert de SQL. Vale. Pues ya lo tenemos todo resuelto. Lo primero que tenemos que hacer es abrir la conexión y crear un string con el comando que queramos insertar. Después ejecutamos el comando, cerramos la conexión y asunto resuelto. Complicado, ¿verdad?

Aquí tenemos el código:

   1: string query = "INSERT INTO EQUIPO VALUES ('" + siglas + "','" + nombre + "')";
   2:  
   3: //usando un command builder, para evitar un sql injection como el siguiente:
   4: //insert into equipo values ('mer', 'merida fc'); delete from equipo where siglas='her';-- '');
   5:  
   6:        
   7: SqlCommand command = new SqlCommand(query, Conexion.Instancia);
   8:  
   9: if ( command.ExecuteNonQuery() == 1)
  10: {
  11:     ret = true;
  12: }

Como se aprecia, creamos un objeto SqlCommand con el string de la instrucción que queremos ejecutar (nótese que también podrían valer delete y update) junto con el SqlConnection. El SqlCommand tiene varios métodos de ejecución, entre ellos el ExecuteNonQuery que nos devuelve la cantidad de filas que se han modificado al ejecutar la instrucción. Sencilo e intuitivo, ¿verdad?

Pero lamentablemente, cada vez que alguien hace esto, Dios mata a un gatito. Esto es una muestra de una mala práctica, ya que no controla el fallo de SqlInjection. Este fallo consiste en algo normal y se produce por las siguiente causas:

  • Mal diseño: Tu capa de presentación no valida los datos.
  • Mal diseño: Tu capa de lógica no valida los datos.
  • Mal diseño: Tu aplicación provoca que se alteren datos que no debe.
  • Desastre: Borrar todo, seguridad?

En vista al código anterior, ¿que podríamos hacer en el código anterior? Un ejemplo bruto sería insertar en el campo del formulario el siguiente código:

   1: '); DELETE MASTER;

Lo cual la capa de datos, recibiría la siguiente cadena a ejecutar:

   1: INSERT INTO EQUIPO WHERE VALUES('');
   2: DELETE MASTER;
   3: ');

Sobran las palabras. ¿Qué soluciones dispone .NET para que esto no ocurra? El propio objeto SqlCommand. Anteriormente insertábamos como string toda la secuencia de comandos, con lo que la validación es muy compleja. Si en lugar de ello empleamos parámetros, estamos ganando en seguridad y estabilidad, además de la limpieza de código. La clase SqlCommand se encarga de validar los datos y evita que se pueda producir un SqlInjection. Veamos paso a paso cómo se hace:

   1: string query = "INSERT INTO EQUIPO VALUES (@siglas, @nombre)";
   2:  
   3: SqlCommand command = new SqlCommand(query, Conexion.Instancia);
   4: command.Parameters.Add(new SqlParameter("@siglas", siglas));
   5: command.Parameters.Add(new SqlParameter("@nombre", nombre));
   6:  
   7: if (command.ExecuteNonQuery() == 1)
   8: {
   9:     ret = true;
  10: }

A través del carácter @, indicamos que lo siguiente es un parámetro. Nótese que no importa siquiera el tipo de dato. Posteriormente, se crean los parámetros y se indexan internamente en el SqlCommand. Mediante SqlCommand.Parameters podemos acceder a ellos.

Como hemos visto, esto garantiza una cierta seguridad en el acceso a la BD de nuestra aplicación, además de aumentar la mantenibilidad del código y de la propia aplicación.

[eMeS] Videos del juego

Después de mucho sufrimiento, nos quedamos fuera de la Imagine Cup. De todas formas, tengo el placer de mostrar dos de los primeros videos que hemos publicado:

El primero de estos videos es el tráiler del juego. La protagonista del juego es Sara, que se embarcará en un mundo de fantasía llamado Iredia. Descubriremos cómo los sonidos toman forma y sentido, nos sumergiremos dentro del oído humano para comprenderlo, conoceremos criaturas misteriosas que nos ayudarán a atravesar este mágico mundo. ¿Suena apetecible, verdad? Aquí tenéis el video:

Por otra parte, uno de los trabajos que más importantes a la hora de elaborar en los videojuegos son las herramientas internas del equipo de desarrollo. Siempre que doy una charla de introducción a videojuegos con XNA, lanzo la siguiente pregunta “¿Qué aplicaciones conocéis que se puedan emplear para hacer un videojuego?”. La gente responde 2 ó 3, hasta que les muestro una diapositiva con un total de 50 aplicaciones comerciales distribuidas en diferentes secciones de videojuego: desde el motor de físicas, hasta sistemas de networking, programas de diseño 3d, retoque fotográfico, IDE’s…hasta programas de gestión de proyecto. En nuestro caso, hemos desarrollado dos herramientas internas. Una de ellas, llamada SpriteSheetPacker, se emplea para generar los sprites desde los diversos frames de todos los elementos que dibujan el equipo de arte. Con ello creamos varios catálogos, como por ejemplo el catálogo de Sara, Animales, ciudad, campo, etc.

Otra de las herramientas y más enfocada al diseño del juego es el editor de niveles, que como su nombre bien indica sirve para crear y editar todos los niveles. A través de esta herramienta podemos colocar todo tipo de elementos en los mapas, como por ejemplo nubes, personajes, fondos, árboles, suelos, colisiones… además de otros elementos que no se ven, como los waypoints (que sirven para que elementos recorran paths definidos por el mapa) los puntos de inicio y muerte además como los disparadores de eventos. Con estos disparadores se ejecutan programas de scripts que hemos creado, y estos scripts también se pueden crear y editar desde el propio editor. Un ejemplo de script es el resultado de eventos que se producen, como una roca que cae. Sin más dilación, aquí dejo el video:

P.D: Remarco que los videos son algo antiguos y hay infinidad de cosas que han mejorado y cambiado. Pero esas cosas, ya las veréis cuando el juego se lance al mercado!

lunes, 21 de junio de 2010

Probando código

   1: if (funciona )
   2: {
   3: System.Console.WriteLine(“Fiestah”);
   4: }
   1:  int x = 5;
   1:  //Esto es un comentario
   2:  int x = 5;
   3:  int y = 10;
   4:  if ( y -5  > 5 )
   5:  {
   6:   
   7:  }