SQL CE – Un “DataContext” para gobernarlos a todos.

Este Post, originalmente lo escribí para mi blog personal, el día 15/07/2011

Lo primero que debemos de conocer es como se va a organizar la estructura de los datos en nuestras BBDD, gestionadas por “Mango”, para ello lo primero que debemos de conocer es el funcionamiento en profundidad de LINQ to SQL. ¿Porque LINQ to SQL?, por que será la única forma de interactuar con SQL CE, ya que no existirán las conexiones directas contra las bases de datos.

Según MSDN en sus librerías para Windows Phone “LINQ to SQL proporciona un enfoque orientado a objetos para trabajar con datos y contar con un modelo de objetos en tiempo de ejecución.” o dicho de otra manera “el modelo de datos de una base de datos relacional se asigna a un modelo de objetos expresado en el lenguaje del programador”.

Para realizar toda esta magia de poder manejar los datos como objetos, se utiliza un objeto principal denominado DataContext, que, otra vez según MSDN “actúa como un proxy para la base de datos local”. Este objeto esta recogido en el espacio de nombres System.Data.Linq.DataContext.

Para aproximarnos a su funcionamiento en los entornos de Windows Phone “Mango”, podremos seguir la siente imagen: ImagenDataContext

Una vez que conocemos que todo gira en torno al DataContext, deberíamos de tener en cuenta las diferencias entre el DataContext utilizado en nuestros entornos móviles y el DataContext utilizado en entornos de escritorio.

  • Lo primero que debemos saber es que no están soportados todos los tipos y clases soportados en el namespace System.Data.Linq y que los que están soportados lo están de forma parcial.
  • Como ya comente en la entrada preliminar, no esta soportado la utilización del lenguaje Transact-SQL.
  • Los objetos de datos de ADO.NET, tampoco están soportados, como por ejemplo el objeto DataReader. Todo, absolutamente todo se utiliza como una colección de objetos del tipo especificado por el DataContext.
  • Los formatos binary de datos tampoco están soportados. Mejor dicho si lo están pero no de forma directa, se deberán de crear tipos propios y parsearlos contra los tipos binarios de nuestra base de datos.
  • En este caso LINQ to SQL solo funciona con SQL CE.

Para conocer mas en profundidad que o que no esta soportado en LINQ to SQL para Windows Phone, debéis visitar como no MSDN.

Creación del DataContext.

Como he comentado lo primero es la creación del DataContext, para ello lo primero que debemos de hacer es añadir la referencia del ensamblado System.Data.Linq. AddReferenceLinq Ahora creamos la clase del tipo DataContext.

   1: public class ContextodeDatos : DataContext

   2: {

   3:     public ContextodeDatos(string CadenaConexion) : base(CadenaConexion)

   4:     {

   5:     }

   6: }

El DataContext es como venimos diciendo todo el tiempo, el que se encarga de manejar los datos en si, para ello debemos de tener la referencia a los objetos (datos), que vamos a utilizar. Con lo que previamente al paso de crear el contexto de datos, deberíamos de haber creado la clase que mapea los datos, es decir el objeto puente entre los datos reales contenidos en la BBDD y LINQ to SQL. Estos objetos se denominan comúnmente objetos POCO (Plain Old CLR Object)

En este ejemplo vamos a tener una base de datos con 2 tablas, Autores y Libros, y obviamente estas dos tablas tendrán sus correspondientes campos. El esquema de ambas es el que se detalla a continuación. Tablas1

Como hemos comentado deberemos de crear una serie de clases que mapeen a cada una de las tablas “físicas” de la BBDD, comenzaremos por crear la primera de ellas sobre la tabla “Autores”. Para guiarnos de una forma sencilla las denominaremos como las tablas a las que mapean.

No debemos de olvidarnos de añadir en el uses de nuestro fichero la referencia al namespace System.Data.Linq.Mapping.

   1: [Table(Name="Autores")]

   2: public class Autor

   3: {

   4:     [Column(IsPrimaryKey=true, IsDbGenerated=true)]

   5:     public int ID { get; set; }

   6:  

   7:     [Column]

   8:     public string Nombre { get; set; }

   9:  

  10:     [Column]

  11:     public string Apellidos { get; set; }

  12:  

  13:     [Column]

  14:     public string Pais { get; set; }

  15: }

Tras crear la clase Autores, crearemos la clase Libros.

   1: [Table(Name="Libros")]

   2: public class Libro

   3: {

   4:     [Column(IsPrimaryKey=true)]

   5:     public string ISBN { get; set; }

   6:  

   7:     [Column]

   8:     public string Titulo { get; set; }

   9:  

  10:     [Column]

  11:     public decimal Precio { get; set; }

  12:  

  13:     [Column]

  14:     public string Editorial { get; set; }

  15:  

  16:     [Column]

  17:     public string Autor { get; set; }

  18:  

  19:     [Column]

  20:     public string Idioma { get; set; }

  21: }

Lo primero de lo que nos damos cuenta es de los atributos utilizados en la creación de ambas clases. Podemos ver aquí la lista completa de los atributos que se pueden utilizar a la hora de mapear los datos en LINQ to SQL. Tenemos que tener en cuenta que no todos los atributos son soportados. En nuestro caso solo hemos utilizados dos de forma muy sencilla:

[Table]: Atributo para indicar que la clase mapea una tabla de datos. Además hemos utilizado una propiedad de este atributo (la única posible así mismo), denominada “Name”, por la que indicamos el nombre de la tabla dentro de la BBDD.

[Column]: Atributo para indicar que el miembro de la clase se mapea a una columna de la tabla, a un campo de la tabla. En este caso hemos utilizado dos propiedades de este atributo:

  • IsPrimaryKey: Por la que indicamos que columna o columnas forman parte de la clave primaria de la tabla.
  • IsDbGenerated: Con esta otra propiedad indicamos que columna es auto-generada por la base de datos. En este caso que la columna es auto incremental.

Como podemos observar el mapeo de las bases de datos es algo bastante latoso, en este caso tenemos simplemente dos tablas muy sencillas dentro de una base de datos bastante normalita, este tema en un entorno real puede convertirse en algo bastante lioso. No existen aun herramientas de modelado o de mapeo automático para este tipo de clases, de forma nativa con Visual Studio pero si que existen herramientas de terceros que pueden ayudarnos a realizar estas tareas de una manera mas visual y mas cómoda. En posteriores post hablare de ellas.

Bueno pues seguimos con nuestro contexto. Anteriormente creamos la clase del tipo DataContext, ahora lo único que debemos de hacer es referenciar nuestros mapeos de las tablas creadas dentro de ese contexto de datos.

   1: public class ContextoDeDatos : DataContext

   2: {

   3:     public ContextoDeDatos(string CadenaConexion) : base(CadenaConexion)

   4:     {

   5:     }

   6:  

   7:     public Table Autores

   8:     {

   9:         get { return this.GetTable(); }

  10:     }

  11:  

  12:     public Table Libros

  13:     {

  14:         get { return this.GetTable(); }

  15:     }

  16: }

Bien, una vez con todo esto lo unico que nos queda es interactuar con nuestra base de datos, para ello lo que haremos es comprobar a la hora de inicializar nuestra aplicacion, si la base de datos existe y si esta no existe, la crearemos.

   1: // Constructor

   2: public MainPage()

   3: {

   4:     InitializeComponent();

   5:  

   6:     string ConnectionString = "Data Source='isostore:/Pruebas.sdf'";

   7:  

   8:     using (ContextoDeDatos Contexto = new ContextoDeDatos(ConnectionString))

   9:     {

  10:         if (Contexto.DatabaseExists() == false)

  11:         {

  12:             Contexto.CreateDatabase();

  13:         }

  14:     }

  15: }

Lo primero que nos debe de resultar un tanto extraño es el formato de la cadena de conexión utilizada, a grandes rasgos le estamos diciendo a nuestra aplicación que la base de datos se encuentra dentro del Isolated Storage de la propia aplicación y que en la ruta raíz de ese Isolated Storage el fichero se llama Pruebas, con la extensión común a SQL Server Ce “.sdf”.

De momento lo dejamos aquí, en el próximo post, hablare de donde exactamente se encuentra nuestra base de datos, como podemos acceder a ella de forma remota, para comprobarla y demás, así como un repaso de las herramientas de terceros que nos pueden facilitarnos un poco la vida en la creación del mapeo de nuestras bases de datos.

En el fichero superior podéis encontrar el código fuente de la pequeña aplicación de ejemplo en donde se utiliza todo lo explicado anteriormente.

Nota: “Ash nazg durbatulûk, ash nazg gimbatul… Ash nazg thrakatulûk agh burzum-ishi krimpatul” es el texto completo escrito en la lengua de Mordor, el cual estaba inscrito en el Anillo que portó, primero, Bilbo Bolsón y luego Frodo Bolsón, propiedad de Sauron, cuya traducción es “Un anillo para gobernarlos a todos, un Anillo para encontrarlos, un Anillo para atraerlos a todos y atarlos en las Tinieblas”.

3 comentarios sobre “SQL CE – Un “DataContext” para gobernarlos a todos.”

  1. Gracias por comentar mi blog. La nota no es subliminal es directa.. jeje.

    Tengo la intencion de escribir bastante mas sobre SQL CE para Mango, o mejor dicho ya para Windows Phone 7.5

Responder a rserna Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *