Buscar este blog

viernes, 25 de febrero de 2011

Creando DataSets tipeados a partir de cualquier XML

Un DataSet tipeado es muy útil ya que nos permite acceder a los datos del DataSet por medio de tipos fuertes usando los nombres de las columnas y con comprobación de parte del compilador.
La forma de crear un DataSet de este tipo es con el editor de DataSets que es en realidad un editor de esquemas xml.
Una propiedad del xml es que se puede inferir su esquema prográmaticamente y usar el resultado para crear un el DataSet tipeado, esto se hace leyendo el xml en un DataSet sin tipos y usando el método WriteXmlSchema del DataSet para escribir el esquema en un archivo, se incluye el archivo en el proyecto en que se desea usarlo y al abrirlo Visual Studio crea automáticamente el código y los archivos de soporte necesarios para el DataSet tipeado.

Aquí esta el código para crear el Dataset.

   1:  DataSet schemaCreator = new DataSet();
   2:  schemaCreator.ReadXml("peliculas.xml");
   3:  schemaCreator.WriteXmlSchema("peliculas.xsd");

Por ejemplo para el siguiente XML.

   1:  <Peliculas>
   2:    <Pelicula>
   3:      <Titulo>Mazinger</Titulo>
   4:      <Director>Jackie Chan</Director>
   5:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   6:      <Actores>
   7:        <Actor>
   8:          <Nombre>John Wayne</Nombre>
   9:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  10:          <Roles>
  11:            <Rol>
  12:              <NombrePelicula>Mazinger</NombrePelicula>
  13:              <NombreRol>Estrella</NombreRol>
  14:            </Rol>
  15:          </Roles>
  16:        </Actor>
  17:      </Actores>
  18:    </Pelicula>
  19:  </Peliculas>

Nos genera este esquema


Todo esto nos permite usar los métodos  ReadXml y WriteXml del DataSet para cargar el y guardar el contenido xml y usar el mismo de una forma muy similar a una base de datos, también podemos usar Linq contra el DataSet.

Claro que también hay herramientas que nos permiten obtener el esquema del xml sin escribir código, una de ellas es XMLViewer, que es una utilidad para ver el contenido de archivos xml en forma tabular y también obtiene el esquema del archivo, también la herramienta de linea de comandos xsd que se incluye con el SDK de .Net Framework nos sirve para obtener el esquema.

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

sábado, 12 de febrero de 2011

Que es LINQ

Linq es el acrónimo en ingles para Language-Integrated Query que significa Lenguaje Integrado de Consulta y es un subconjunto agregado a los lenguajes de .Net para realizar búsquedas  y otras operaciones sobre conjuntos de datos, esto es: el mismo lenguaje de tu preferencia puede realizar operaciones sobre conjuntos de datos proporcionándote verificación por parte del compilador,  Intelisense y verificación de tipos sobre las consultas, la sintaxis es muy parecida a SQL con la ventajas antes mencionadas debido a que no se usan con cadenas como en SQL.

Linq puede realizar consultas sobre diversas formas de conjuntos de datos a través de extensiones especificas al conjunto de datos que estas manejando, así existen por lo menos las siguientes extensiones provenientes de Microsoft y otras fuentes:

Linq a objetos: permite manejar consultas a los tipos básicos de .Net como listas y arreglos y sobre clases ya sea del sistema o propias.
Linq a DataSets: las consultas se hacen sobre los componentes de un DataSet ya sea normal o tipeado.
Linq a SQL: las consultas se realizan sobre la base de datos SQL Server con todas las ventajas antes mencionadas.
DBLinq: es un proyecto independiente que es similar a Linq a SQL con la ventaja de que podemos usar bases de datos diferentes a SQL Server y de hecho podemos cambiar de tipo de base de datos con solo modificar la cadena de conexión.
Linq a XML: nos permite realizar consultas en datos guardados en XML.

Para darnos una idea rápida de la forma en que se utiliza Linq tenemos los siguientes ejemplos sencillos de Linq a datos.
Podemos consultar en un arreglo los elementos que cumplen con cierta condición (c#):


   1:  string[] strings = new string[] { "1", "2", "3", "2", "1" };
   2:  IEnumerable<string> two = from s in strings
   3:                            where s == "2"
   4:                            select s;
   5:  Console.Out.WriteLine("s == 2, count{0}", two.Count());

el mismo código en Visual Basic es prácticamente idéntico:


   1:  Dim strings() As String = New String() {"1", "2", "3", "2", "1"}
   2:  Dim two As IEnumerable(Of String) = From s In strings _
   3:     Where s = "2" _
   4:     Select s
   5:  Console.Out.WriteLine("s == 2, count{0}", two.Count())

El resultado de la consulta es un IEnumerable y tenemos que recorrerlo de alguna forma para obtener resultados, en el ejemplo el método Count (que es un método de extensión) recorre el resultado de la consulta y nos entrega la cuenta de los elementos que cumplieron con las condiciones.

También podemos consultar más de un conjunto de datos a la vez (c#):



   1:  int[] integers = new int[] { 1234, 754, 309, 233 };
   2:  var query = from i in integers
   3:              from s in strings
   4:              where i.ToString().Contains(s)
   5:              select new { s, i };
   6:  foreach(var i in query) {
   7:      Console.Out.WriteLine("{0}, {1}", i.s, i.i);
   8:  }

en Visual Basic:

   1:  Dim integers() As Integer = New Integer() {1234, 754, 309, 233}
   2:  Dim query = From i In integers _
   3:     From s In strings _
   4:     Where i.ToString().Contains(s) _
   5:     Select New With {s, i}
   6:  For Each i In query
   7:      Console.Out.WriteLine("{0}, {1}", i.s, i.i)
   8:  Next

En este caso usamos una consulta que une dos conjuntos y después se recorre la consulta para obtener los resultados.
Para aprender más sobre Linq visita:
Lista de artículos acerca de Linq

miércoles, 9 de febrero de 2011

Leyendo y Escribiendo XML con Linq en Visual Basic

Escribir xml en Visual Basic es tan fácil como se dice simplemente se escribe el xml tal cual en el código de Visual Basic y el compilador convierte el árbol completo en una instancia de la clase XElement:


   1:  Dim  xml As XElement =  <Root> _
   2:      <Elemento /> _
   3:  <Root>

Si necesitamos incluir en el xml el valor de una variable o cualquier código podemos usar los tags <%= >:


   1:  Dim a As String = "Hola"
   2:  Dim  xml As XElement =  <Root> _
   3:      <Elemento><%= a %></Elemento> _
   4:  <Root>

Escribir xml también es sencillo pero no tan directo.
En este ejemplo uso Linq para crear XML desde un árbol de objetos y después poder leer de nuevo el XML con Linq y crear de nuevo los objetos.
Por supuesto para correr los ejemplos hay que crear los tipos de datos necesarios, todas las colecciones son de tipo List(Of T)
Escribir (Linq a XML):


   1:  Dim peliculas As List(Of Pelicula)
   2:  Dim source As New PeliculaTA
   3:  peliculas = source.Retrieve()
   4:  Dim xmlArch As XElement = _
   5:   <Peliculas>
   6:       <%= From m In peliculas _
   7:           Select _
   8:           <Pelicula>
   9:               <Titulo><%= m.Titulo %></Titulo>
  10:               <Director><%= m.Director %></Director>
  11:               <Estrenado><%= m.Estrenado %></Estrenado>
  12:               <Actores>
  13:                   <%= From a In m.Actores _
  14:                       Select _
  15:                       <Actor>
  16:                           <Nombre><%= a.Nombre %></Nombre>
  17:                           <Nacimiento><%= a.Nacimiento %></Nacimiento>
  18:                           <Roles>
  19:                               <%= From r In a.Roles _
  20:                                   Select _
  21:                                   <Rol>
  22:                                       <NombrePelicula><%= r.Pelicula %></NombrePelicula>
  23:                                       <NombreRol><%= r.NombreRol %></NombreRol>
  24:                                   </Rol> _
  25:                               %>
  26:                           </Roles>
  27:                       </Actor> _
  28:                   %>
  29:               </Actores>
  30:           </Pelicula> _
  31:       %>
  32:   </Peliculas>
  33:  File.WriteAllText("peliculas.xml", xmlArch.ToString())

Leer (XML a Linq):


   1:  Dim xmlArch As XElement = XElement.Load("peliculas.xml")
   2:  Dim peliculas = From m In xmlArch...<Pelicula> _
   3:   Select New Pelicula With { _
   4:    .Titulo = m.<Titulo>.Value _
   5:    , .Director = m.<Director>.Value _
   6:    , .Estrenado = m.<Estrenado>.Value _
   7:    , .Actores = (From c In m...<Actor> _
   8:    Select New Actor With { _
   9:   .Nombre = c.<Nombre>.Value _
  10:   , .Nacimiento = c.<Nacimiento>.Value _
  11:   , .Roles = (From r In c...<Rol> _
  12:   Select New Rol With { _
  13:   .Pelicula = r.<NombrePelicula>.Value _
  14:   , .NombreRol = r.<NombreRol>.Value _
  15:   }).ToList() _
  16:   }).ToList() _
  17:   }

El resultado de el último ejemplo es un Enumerable(Of Pelicula) el cual hay que recorrer por ejemplo con For Each para obtener resultados.

Para aprender mas sobre Linq visita:
Lista de artículos acerca de Linq

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

sábado, 5 de febrero de 2011

Tips y errores del control ListView

Te aparece el siguiente error al cargar una  página con un control ListView:
capacity was less than the current size.
Parameter name: value

Esto ocurre cuando tienes un ListView enlazado a un ObjectDataSource con la propiedad EnablePaging en verdadero y el método establecido en SelectCountMethod devuelve un tipo de datos long, para corregir este error tienes que cambiar el método SelectCountMethod para que regrese un int.
Es un error un poco rebuscado pero puede suceder, afortunadamente el tipo int puede manejar la gran mayoría de los usos y en todo caso quien va a paginar tantos datos.

jueves, 3 de febrero de 2011

Pruebas unitarias con Nunit

Las pruebas unitarias son muy importantes en el proceso de desarrollo de una aplicación, para realizarlas podemos usar las herramientas incluidas en Visual Studio, pero no todas las versiones tienen esta característica, y por supuesto esta la gente que no usa Visual Studio, Aquí es donde entra Nunit que es un framework para realizar pruebas unitarias que no depende en lo absoluto de Visual Studio.
Nunit es la version para Net Framework del original Junit que es la versión para Java y se puede obtener de la pagina oficial de Nunit.
Una vez instalado creamos de preferencia un proyecto separado para nuestras pruebas este proyecto puede  ser preferentemente de tipo librería de clases ya que toda la interacción con nuestras pruebas se hace usando el ejecutable de Nunit, A este proyecto añadimos una referencia a la dll nunit .framework.dll que se encuentra en el directorio en que se instalo Nunit (no en el GAC), también añadimos una referencia al proyecto que vamos a probar y empezamos a crear las pruebas.
La forma básica en que se crea una prueba es creando una clase que tiene aplicado el atributo TestFixture a esta clase le añadimos métodos con el atributo Test aplicado estos métodos son los que utilizaremos para crear las pruebas por supuesto podemos añadir también clases y métodos sin los atributos mencionados que podrían ser para ayudar en el proceso de prueba.
En nuestros métodos de prueba lo que haremos es usar los métodos de Nunit para comprobar que nuestras clases den los resultados esperados, el mas comúnmente usado es el metodo AreEqual de la clase Assert de Nunit que compara una variable contra un valor esperado.
Aquí esta el ejemplo, lo primero que les muestro es la clase que vamos a probar:


   1:  namespace Prueba.Data {
   2:      public class User {
   3:          public string Name { get; set; }
   4:          public string Password { get; set; }
   5:          public User(string name, string password) {
   6:              Name = name;
   7:              Password = password;
   8:          }
   9:      }
  10:  }

Y después nuestra clase de prueba:


   1:  using NUnit.Framework;
   2:  using Prueba.Data;
   3:   
   4:  namespace NunitTests {
   5:      [TestFixture]
   6:      public class UserTest {
   7:          [Test]
   8:          public void ConstructorTest() {
   9:              User user = new User("Pedro", "secreto");
  10:              Assert.AreEqual("Pedro", user.Name);
  11:              Assert.AreEqual("secreto", user.Password);
  12:          }
  13:      }
  14:  }

Una vez que tenemos listas las pruebas compilamos el proyecto y abrimos el ejecutable de Nunit con el que se realizaran las pruebas.
En Nunit usamos el menú File -> Open Project y abrimos la dll que se genero al compilar el proyecto, en el panel izquierdo aparecerá un árbol que contiene todos los métodos que creamos para las pruebas en una jerarquía que sigue a la del proyecto, podemos ejecutar un solo método una rama del arbol o todas las pruebas a la vez.
En este caso solo tenemos una prueba presionamos el botón Run y se ejecutara el proyecto de pruebas una barra de progreso nos muestra el porcentaje de pruebas ejecutadas según se van ejecutando y el color verde nos indica que ninguna ha fallado en caso contrario cambiara a color rojo.
Si al final hubo errores se mostraran en el árbol y en los paneles inferiores mostrando la prueba que fallo e información acerca de el error incluyendo la posición en el código que fallo, también podemos depurar el código en la ejecución usando el depurador de Visual Studio u otro depurador escogiendo la instancia de Nunit como el ejecutable a depurar.



Por supuesto NUnit puede probar muchas más cosas que la igualdad de miembros, por ejemplo algo muy útil es que puede probar cuando un método manda una excepción en el momento adecuado, pero la API de NUnit es muy amplia para un blog y lo mejor es que te dirijas a la documentación de NUnit para la última versión para una mejor referencia.
Para aprender más acerca de las pruebas unitarias con .Net Framework visita:
Lista de artículos acerca de pruebas unitarias con .Net Framework

miércoles, 2 de febrero de 2011

Usando el control TemplatePagerField en un DataPager

Una de las características del control DataPager es que nos brinda un área donde podemos mostrar información relevante a la paginación (en realidad podemos mostrar cualquier cosa en esta área pero lo lógico es que la relacionemos con la paginación), tal como la pagina en la que estamos, el total de paginas o el numero de registro en que inicia la pagina, esto se logra añadiendo un Field TemplatePagerField en el template Fields del DataPager y editando el template PagerTemplate del control, en este template podemos poner cualquier código Asp.Net y lo importante es que tenemos acceso a las propiedades del DataPager con lo que podemos mostrar la información antes mencionada.
Aquí tenemos el ejemplo de un DataPager que muestra el número de registro que se muestra y el total de paginas disponibles.


   1:  <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" 
   2:      PageSize="3">
   3:      <Fields>
   4:          <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" 
   5:              ShowNextPageButton="False" ShowPreviousPageButton="False" />
   6:          <asp:NumericPagerField />
   7:          <asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="True" 
   8:              ShowNextPageButton="False" ShowPreviousPageButton="False" />
   9:          <asp:TemplatePagerField>
  10:              <PagerTemplate>
  11:                  <br />
  12:                  <asp:Label runat="server" Text="<%# Container.StartRowIndex  %>"/>
  13:                  &nbsp;-
  14:                  <asp:Label runat="server"
  15:                      Text="<%# Container.StartRowIndex +  Container.PageSize %>"/>
  16:                  &nbsp;de
  17:                  <asp:Label runat="server" Text="<%# Container.TotalRowCount  %>"/>
  18:              </PagerTemplate>
  19:          </asp:TemplatePagerField>
  20:      </Fields>
  21:  </asp:DataPager>

Los propiedades del DataPager relacionadas con la paginación son:
StartRowIndex: el número del primer registro mostrado
PageSize: el total de registros mostrados en cada pagina
TotalRowCount: el total de registros disponibles para la paginación

Para aprender más sobre el control DataPager busca en la lista de artículos sobre el control DataPager en este blog.