Para complementar la serie de post que sobre LINQ To Entities y Visual Basic 2008 ha iniciado Jorge Serrano, en este primer post sobre ADO.NET Entity Framework os daré el punto de vista análogo a lo que Jorge ha explicado pero aplicado a la nueva versión de C # que aparece como una de las grandes novedades de Visual Studio 2008: C # 3.0. Antes de entrar en materia, la primera pregunta que se nos puede venir para los profanos en la materia es ¿Qué es ADo.NET Entity Framework? Como se describe en este artículo, una de las metas principales de la nueva versión de ADO.NET es elevar el nivel de abstracción de la programación contra fuentes de datos a través de la eliminación del "vacío" existente entre los modelos de datos y los lenguajes de programación. Y ¿Cómo es posible esto? A través de dos innovaciones claves de las que ya se ha hablado mucho en Geek.Ms: LINQ y ADO.NET Entity Framework. Precisamente éste último (Entity Framework) es un nuevo componente que aparece en familia de tecnologías ADO.NET, que habilitará acceso a datos mediante LINQ utilizando: LINQ To SQL, LINQ To DataSet y/o LINQ To Entities. Si tuviésemos que resumir las características de este Entity Framework, sin duda destacaríamos los siguientes puntos:
- Se trata de un Framework que permite manipular y acceder a los datos como clases .NET.
- Permite realizar un modelado de datos a nivel conceptual, es decir, habilita la separación de las aplicaciones y los esquemas de BD.
- Permite una mejor interactuación de los datos con el entorno .NET: Se interactúa con objetos, frente a hacerlo con filas y columnas.
- Proporciona una serie de servicios en tiempo de ejecución y en tiempo de diseño que permite a los desarrolladores describir los datos de la aplicación e interactuar con ellos a un nivel de abstracción conceptual claramente alineado con el concepto de implementación de aplicaciones de negocio, y que además ayuda a aislar la aplicación respecto a los esquemas de base de datos (BD) sobre los que se ha definido.
- Como comentó Jorge en su post, se apoya en LINQ para definir las consultas a objetos del esquema EDM (Entity Data Model).
- Supone una capa más, pero independiza las aplicaciones de el esquema de BD subyacente, independientemente de la tecnología de BD que se esté utilizando.
¿En qué se traduce esta independencia con el esquema de BD y la tecnología de BD? Pues básicamente en una arquitectura dividida en dos partes diferenciadas, Modelo de datos y Modelo Conceptual (EDM), en la que el paso de una parte a otra se realiza a través del correspondiente mapeo. Para realizar este mapeo se utilizan proveedores .NET que permiten interactuar con los datos en cada uno de las partes:
|
| La idea es que el provider .NET de la capa de datos se encarga de traducir las operaciones de datos realizadas en la capa conceptual a un lenguaje entendible por la BD (lógicamente T-SQL). Por su parte, el proveedor .NET (EntitySQL) de la capa conceptual traduce las consultas LINQ realizadas en las aplicaciones a las correspondientes instrucciones que interactúen con el modelo conceptual definido mediante el proceso de mapeo. |
Una vez repasadas las principales ideas y conceptos que hay bajo ADO.NET Entity Framework, vamos a ver en la práctica en que consiste trabajar en un nivel de abstracción superior. Los requisitos para poder probar ADO.NET Entity Framework ya los comentamos en este post.
Definiendo el EDM
Cómo comentó Jorge en su post, el primer paso para trabajar con ADO.NET Entity Framework pasa por crear un modelo de entidades a partir de un cierto esquema de BD. Para ello añadimos al proyecto un elemento de tipo ADO.NET Entity Data Model con lo que se iniciará un asistente que nos guiará en la creación del modelo a partir de:
- Especificar la opción de generación del EDM (a partir de una BD o bien un EDM vacío.
- Especificar la cadena de conexión a la BD (que como siempre, puede ser un archivo físico o bien una instancia de SQL Server).
- Especificar que objetos de la BD queremos que formen de nuestro EDM (en este caso, tablas y procedimientos almacenados).
Tras pulsar Finish en la última pantalla del asistente, ya tendremos creado el modelo de entidades que en esencia es un fichero .edmx que contiene toda la definición del modelo. Si inspeccionamos el modelo veremos:
- Se han generado tantas entidades como tablas de la BD relacional.
- Al seleccionar cada entidad, podremos ver los detalles de la misma en cuanto a miembros y la correspondencia de los campos de la entidad con sus equivalentes en la tabla de la BD.
- El explorador del modelo nos permitirá ir navegando por los componentes del mismo: entidades, asociaciones entre entidades, funciones, etc.
- Finalmente, para tener una idea del código generado por el asistente, basta con que nos vayamos al Class Viewer o al Object Browser e inspeccionemos los distintos elementos generados.
Consultando Entidades
Como ya comentó Jorge, una de las formas que tenemos para definir consultas contra el EDM es a través de LINQ To Entities que nos dota de toda la potencia y capacidades de LINQ sobre ADO.NET Entity Framework, así como funcionalidad de ORM (Object Relational Model), de manera que los desarrolladores pueden materializar sus entidades en tipos del CLR y programar de forma más sencilla contra el EDM y la base de datos. Lo primero que tenemos que hacer es añadir a nuestra aplicación las sentencias using necesarias:
- using System.Data.EntityClient;
- using System.Data.Common;
- using System.Data;
El siguiente paso consiste en instanciar el modelo EDM creado y definir la correspondiente consulta LINQ. Por ejemplo:
| //Instancia del modelo de entidades creado ClientesModel.Entidades_BD_Clientes ModeloClientes= new ClientesModel.Entidades_BD_Clientes(); //Consulta de entidades! var clientes = (from c in ModeloClientes.Md_Clientes from v in ModeloClientes.Md_Vehiculos where c.ID_Cliente==v.ID_Cliente select c).Distinct(); Console.WriteLine("***********Consulta LINQ To Entities***********"); foreach (var c in clientes) { Console.WriteLine("NIF={0}, Direccion={1}", c.ID_Cliente, c.DireccionCliente + " " + c.CiudadCliente); } Console.ReadLine(); |
Como vemos, lo primero que hacemos es crear un objeto denominado ClientesModel que es una instacia de ClientesModel.Entidades_BD_Clientes(). La primera parte se corresponde a nuestro EDM, y la segunda (Entidades_BD_Clientes) es un objeto que ha sido añadida al modelo en el momento de su creación y que hereda de ObjectContext, clase que se encarga de mantener la conexión e información de los metadatos necesaria para leer, escribir, actualizar o borrar entidades en la BD. Además, también referencia la clase ObjectStateManager que se encarga de aspectos relacionados con el tracking de cambios y la resolución de identidades...esto ya lo vimos con LINQ To SQL: si una consulta nos devuelve un objeto del modelo, este es persistido a través de otras consultas mientras que exista el objeto de contexto correspondiente. Sin más, la salida por pantalla que se obtiene de la consulta anterior es:
Operaciones de actualización, insercción y borrado de entidades
Como ocurría con LINQ To SQL, ADO.NET Entity Framework a través de LINQ To Entities nos permite realizar de manera sencilla operaciones de actualización, inserción o borrado a través de la interactuación con las entidades del modelo. Para actualizar una entidad, basta con crear una instancia de la misma a partir de realizar una consulta a la BD de los resultados a actualizar (consulta con C # plano o mediante query expression):
| //Actualización Console.WriteLine("***********Actualizando las Entidades***********"); ClientesModel.Md_Clientes ClienteToUpdate = ModeloClientes.Md_Clientes.First( c => c.ID_Cliente == "71505286B"); ClienteToUpdate.CiudadCliente="Torrelavega"; ModeloClientes.SaveChanges(); foreach (var c in clientes) { Console.WriteLine("NIF={0}, Direccion={1}", c.ID_Cliente, c.DireccionCliente + " " + c.CiudadCliente); } |
Como vemos, la clave para llevar los datos a la BD está en el método SaveChanges(). Por otro lado, tal y como sucede con el caso de la primera consulta, gracias a que el objeto ObjectStateManager de encarga del tracking de los datos, los antiguos y nuevos valores se mantienen en el contexto de la aplicación y los cambios se pueden guardar en la BD. La salida por pantalla de la operación de actualización es:
Para añadir una entidad nueva basta con crear una nueva instancia de la entidad deseada, especificar sus propiedades y añadirla al modelo:
| //Insercción Console.ReadLine(); Console.WriteLine("***********Añadiendo nuevas Entidades***********"); ClientesModel.Md_Clientes ClienteToAdd = new ClientesModel.Md_Clientes(); ClienteToAdd.ID_Cliente = "72678934C"; ClienteToAdd.DireccionCliente = "C/ Ordoño II"; ClienteToAdd.CiudadCliente = "León"; ModeloClientes.AddToMd_Clientes(ClienteToAdd); ModeloClientes.SaveChanges(); var AllClients = (from c in ModeloClientes.Md_Clientes select c); foreach (var c in AllClients) { Console.WriteLine("NIF={0}, Direccion={1}", c.ID_Cliente, c.DireccionCliente + " " + c.CiudadCliente); } Console.ReadLine(); |
En este caso la clave para preservar los datos en la BD está en el método AddToMd_Clientes() que es generado automáticamente en el modelo de creación del EDM y que recibe un objeto del tipo de la entidada a añadir, así cómo en el método SaveChanges(). La correspondiente salida por pantalla es:
Para realizar el borrado de una entidad, se sigue la misma filosofía que para el caso de la actualización e insercción, sólo que en este caso se utiliza el método DeleteObject() y a continuación SaveChanges() para poder llevar los datos a la BD:
| //Borrado Console.WriteLine("***********Borrado de clientes***********"); ClientesModel.Md_Clientes ClienteToDelete = ModeloClientes.Md_Clientes.First( c => c.ID_Cliente == "72678934C"); ModeloClientes.DeleteObject(ClienteToDelete); ModeloClientes.SaveChanges(); Console.WriteLine("Clientes después de borrar"); foreach (var c in AllClients) { Console.WriteLine("NIF={0}, Direccion={1}", c.ID_Cliente, c.DireccionCliente + " " + c.CiudadCliente); } Console.ReadLine(); |
La correspondiente salida por pantalla es:
Y hasta aquí este primer post sobre ADO.NET Entity Framework en la práctica. En el próximo post os introduciré el concepto de Entity SQL y Entity Services, y os mostraré una interesante herramienta que tenemos disponible para facilitar la construcción de consultas contra un EDM. Espero que el post os haya resultado interesante.
Comparte este post: