EF 4.0: POCO y proxies dinámicos

Para ser sinceros, entre el comienzo del nuevo libro de EF 4.0 y el papel en blanco que esto representa, no sabía por dónde empezar a escribir sobre EF. Son tantas y en mi opinión tan acertadas las nuevas novedades que no tenía ni idea del sitio en el que poner mi granito de arena.

Desde la primera versión, y por ahora única, de Entity Framework, muchas han sido las reclamaciones y recomendaciones de mejora que este framework ha recibido por parte de la comunidad, seguro muchos conocéis el famoso “Vote of No Confidence”  que algunos MVP firmaron y que tanto revuelo levanto en su tiempo. De todas las recomendaciones y falta de confianza en esta primera versión del producto una muy comentada fue el hecho de no poder disponer de objetos POCO dentro de nuestro modelos de dominio, algo imprescindible para incluir el concepto de ignorancia de la persistencia, PI ( Persistent Ignorant ) dentro de nuestros desarrollos.

Por suerte, en esta segunda versión esta feature tan solicitada está disponible dentro de la nueva versión del producto, así como plantillas T4 para la generación automática de las clases del modelo. Para una introducción rápida podéis leer los infinitos blogs que tratan este tema, y como no, en esta misma comunidad mis vecinos de blog, Juan Carlos y Alberto Diaz tienen entradas relativas que recomiendo leer.

Objectos POCO

Para no repetirme en el tema, en mi entrada me gustaría comentar algunas interioridades de estos objetos POCO y como trabajan internamente. Me imagino, que al igual que yo, una pregunta que os haréis es como se gestionan los cambios que sobre estos objetos se producen, dentro del ámbito de un contenedor, para que posteriormente puedan ser llevados hasta el almacen relacional configurado y como se manejan las relaciones entre los mismos.

Pongámonos en contexto y empecemos definiendo, tal y como muestran las entradas anteriormente mencionadas, un par de entidades, que denominaremos Blog y Post, mostradas a continuación.

 

 

 

Ahora realicemos una sencilla operación de cambio en un conjunto de entidades, por ejemplo los blogs almacenados en nuestro almacen de datos:

 

Si comprobamos nuestra base de datos veremos como estos cambios se han realizado correctamente, ¿como es posible esto? Fijaos que en nuestras clases Blog y Post ya no disponemos de los eventos RaisePropertyChanged que notificaba a la infraestructura un cambio en el valor de esta propiedad, sin embargo todo sigue funcionando correctamente. Como os podéis haber imaginado alguien se ha encargado de sincronizar nuestros objetos POCO con  los elementos que manejan el estado de todas las entidades dentro de la infraestructura de Entity Framework, nuestras ya famosas e hiper-conocidas ObjectStateEntry.

Este proceso de sincronización de cambios puede realizarse de dos formas diferentes, la primera de forma imperativa mediante una llamada a un nuevo método de los contextos de trabajo llamado DetectChanges, y el segundo, como hemos visto en nuestro objeto, de forma implícita en la llamada a SaveChanges, el cual en su implementación ya realiza este proceso por defecto.

Por supuesto, por poner pegas que no sea, este sistema no es del todo eficiente, pensemos que en realidad el proceso es básicamente la creación de un snapshot de las entidades materializadas y posteriormente comparar estos snapshot con los elementos a guardar para conocer o sincronizar los cambios. ¿Cómo podemos mejorar este proceso? La respuesta es mediante los “Change Tracking Proxies” de los cuales hablaremos a continuación.

 

Algunas notas importantes sobre los Objetos POCO

Una característica que los objetos POCO también deben soportar es el manteniemiento de las relaciones entre los objetos,asegurando la consistencia de las relaciones. Aunque este trabajo lo podemos hacer nosotros a mano tal y como se muestra en el siguiente enlace en la sección Fix-up relationships la plantilla por defecto que el equipo de producto de EF nos ofrecerá por defecto ya contendrá esta característica funcamental.

 

Change Tracking Proxies

 

Un Change Tracking Proxy no es mas que una subclase de nuestros objetos POCO que implementa la infraestructura de gestión de cambios que se define en Entity Framework, es decir, implementa la interfaz IEntityWithChangeTracker Por supuesto, con solo decir que es una subclase ya estamos imponiendo una  serie de restricciones dentro de nuestros objetos, por ejemplo el hecho de que no pueda ser una clase sellada. A continuación se muestra una lista de las restricciones que se deben de cumplir para disponer de esta capacidad dentro de nuestros objetos:

 

  1. Las clases POCO no pueden estar selladas
  2. Las clases POCO tienen que tener un constructor por defecto público.
  3. Las propiedades deben declararse como publicas y virtuales para que puedan ser sobreescritas por la subclase.
  4. El tipo de las propiedades de navegación debe de ser ICollection<TEntity>

Veamos un ejemplo en la práctica modificando nuestras entidades anteriores para que cumplan estas restricciones:

 

 

 

Si realizamos un pequeño ejemplo de cambio en una entidad y observamos los valores que el objeto ObjectStateEntry asociado a la entidad tiene en sus valores originales y actuales podremos ver ‘la magia’ de nuestros “change tracking proxies”.

 

 

 

¿De dónde viene esta “magia”? Si observamos con detalle el tipo de Blog obtenido veremos como en realidad el resultado es una subclase emitida en tiempo de ejecución que hará de proxy de nuestros objetos POCO. De esta forma tenemos PI en nuestros desarrollos y rendimiento en la gestión de los cambios de los mismos.

img1

Algunas notas importantes sobre Change Tracking Proxies

 

Aunque el uso de proxies dinámicos es una buena solución, en mi opinión mejor que la inyección de IL como proponen otros MVP , también tienen algunas consideraciones que debemos tratar. La primera y más imporatante es como afectan estos proxies en aplicaciones N-Tier en las que podríamos serializar estas entidades como contratos de datos, puesto que no sabemos a priory el nombre del tipo creado y por lo tanto no lo podremos establecer como KnownType o ServiceKnowType para facilitar el proceso de serialización. Con el fin de soportar esta problemática WCF 4.0 dispone de un nuevo mecanismo para resolver dinámicamente los tipos conocidos por medio de un nuevo elemento llamado DataContractResolver, sobre el cual podréis leer aquí y aquí.

9 comentarios sobre “EF 4.0: POCO y proxies dinámicos”

  1. Alberto no te confundas. Change Tracking Proxy se refiere solamente a la gestión de cambios dentro de un contexto de trabajo, no si mueves estos fuera por medio de una capa de servicios.
    saludos

  2. Uno de los problemas que continuo viendo es la referencia a los campos. En la linea ‘string current = entry.CurrentValues[«Title»].ToString();’, se hace referencia a la columna «Title». ¿Hay alguna forma de resolver esto en EF 4 para evitar errores si cambiamos de nombre el campo de la entidad o de la base de datos ?

    Un Saludo.

  3. Juan, no hay que hacer nada con respecto al tema del manejo de los nombres como Title, de hecho ahora tampoco para crear los ObjectQuery hace falta el nombre, con el tipo llega. En mi ejemplo lo uso porque accedo al ObjectStateManager no a la información de un tipo.

    Saludos
    Unai

  4. ¿Se podria al definir una herecia entre tablas establecer una codicion diferente a la igualdad de un campo?, por ejemplo si un campo es mayor que un valor dado que sea un tipo y si es menor o igual que sea de otro.

    Saludos

    Angel.

  5. Unai, cual crees que el la mejor alternativa para una arquitectura de aplicaciones distribuidas .NET a .NET (Cliente y Servidor)…POCOs o STEs?

Deja un comentario

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