Self-Tracking Entities en Entity Framework 4

por emmanuel  24. agosto 2010

Introducción: tipos de entidades en Entity Framework

Desde la salida de Entity Framework, al generar modelos de entidades, las clases generadas derivan de EntityObject.
Con la salida de la versión 4 de Entity Framework, se incorpora soporte para seleccionar el tipo de entidad de la cual van a derivar nuestras entidades de negocio: a los clásicos EntityObject se agregan como novedad POCO, POCO Proxies y Self-Tracking entities.
Antes de desarrollar las entidades de tipo Self-Tracking (el objetivo de este artículo), es conveniente dar un panorama de estos diferentes tipos de entidades, para poder decidir cual utilizar, dependiendo de la arquitectura de la aplicación a realizar:

  • EntityObject

Por defecto, las herramientas de ADO.NET Entity Data Model generan tipos de entidades que derivan de EntityObject. En este caso, el ObjectContext administra las relaciones entre los objetos, mantiene el historial de los cambios que ocurren (Change-Tracking) y soporta Lazy Loading.

Sin embargo, este tipo de entidades dependen fuertemente del Entity Framework. Si se desea trabajar con arquitecturas que no conocen la forma de persistencia (por ejemplo: TDD, Test-Driven Development), lo más deseable es utilizar entidades de tipo POCO o POCO Proxy.

  • POCO

Entity Framework permite utilizar objetos del dominio existentes junto con el modelo de datos, sin hacer cambios a las clases de datos. Estas clases POCO ("Plain-Old" CLR Objects), son conocidas como objetos que ignoran la persistencia y soportan las mismas funcionalidades de Query, Insert, Update y Delete que los objetos EntityObject.

Al trabajar con entidades POCO, los cambios que se realicen al grafo de objetos no son mantenidos automáticamente por Entity Framework a medida que ocurren, sino que se utiliza un mecanismo de snapshots para detectarlos: se debe llamar a DetectChanges para sincronizar el ObjectContext con el grafo actualizado (por defecto, el ObjectContext llama a este método antes de grabar los datos).

Este mecanismo utiliza mas memoria que el anterior y puede afectar la performance, especialmente si la aplicación requiere la detección de cambios frecuentemente. Para poder tener una notificación instantánea de los cambios, se debe activar la creación de objetos Change-Tracking Proxy, y para activar Lazy Loading se debe activar la creación de Proxies de Lazy Loading.

  • POCO Proxy

Se debe utilizar en los casos en los que se requiera detección de cambios instantánea y Lazy Loading. Al utilizarlo, se tiene la misma funcionalidad que con entidades tipo EntityObject, pero con las clases del dominio separadas del Entity Framework. Los proxies se crean en tiempo de ejecución, lo que implica que las entidades generadas difieren del tipo POCO, introduciendo algunas complicaciones con la serialización. Por otra parte, la creación de proxies consume mas recursos que los objetos POCO.

  • Self-Tracking Entities

Los tres tipos definidos anteriormente funcionan correctamente en aplicaciones donde los objetos pueden ser agregados (Attach) al ObjectContext que maneja el historial de cambios. Sin embargo, cuando se desea transferir un grafo de entidades a una capa donde el ObjectContext no está disponible, se debe decidir como mantener el historial de cambios y reportar esos cambios de vuelta al ObjectContext (por ejemplo: arquitectura en capas, ambientes desconectados, arquitecturas SOA, etc.).

A partir de la versión 4 de Entity Framework, las entidades del tipo Self-Tracking pueden grabar cambios a las propiedades escalares, complejas o de navegación. Este tipo de entidades no dependen del Entity Framework, y son generadas con el template de ADO.NET Self-Tracking Entity Generator.

Self-Tracking Entities

En arquitecturas en capas, el ObjectContext puede no estar disponible en la capa que modifica las entidades. A partir de Visual Studio 2010 (con Entity Framework 4), está disponible el template ADO.NET Self-Tracking Entity Generator. Este template genera dos archivos .tt (text template):

El archivo <nombreModelo>.tt genera los tipos de entidades y una clase helper que contiene la lógica de mantenimiento de cambios, mas los métodos de extensión que permiten establecer el estado de las entidades.

El archivo <nombreModelo>.Context.tt genera un ObjectContext tipado y una clase de extensión que contiene los métodos ApplyChanges para las clases ObjectContext y ObjectSet. Estos métodos examinan la información del historial de cambios para inferir las operaciones a realizar para grabar los cambios en la base de datos.

Para acceder al template se debe hacer click derecho sobre la superficie del diseñador de entidades, y seleccionar “Add Code Generation Item”:

SelfTracking001

 

En la ventana que aparece, seleccionar “ADO.NET Self-Tracking Entity Generator”:

SelfTracking002

Al presionar “Add”, se ejecutarán los templates que crearán las clases necesarias, las cuales contendrán los métodos de extensión necesarios para trabajar con Self-Tracking:

SelfTracking003

Métodos de extensión de Self-Tracking Entities

  • StartTracking

Este método se utiliza para comenzar el Change-Tracking (rastrear cualquier cambio que ocurra en la entidad). Esto incluye propiedades escalares, colecciones y referencias a otras entidades. Las entidades de tipo Self-Tracking inician el Change-Tracking automáticamente cuando son deserializadas en un cliente a través de WCF. También se activa para nuevas entidades creadas en los siguientes escenarios:

  1. Una relación es creada entre la nueva entidad y una entidad que actualmente tiene Change-Tracking activado.
  2. Se llama al método MarkAs o AcceptChanges en una entidad.

 

  • StopTracking

Este método finaliza el Change-Tracking en una entidad.

  • MarkAs

Todos los métodos que comienzan con “MarkAs” activan el Change-Tracking. Estos métodos permiten cambiar el estado de una entidad a Added, Modified, Deleted, o Unchanged, y además retornan la misma entidad a la cual son aplicados, con el estado modificado:

MarkAsAdded cambia el estado de una entidad a Added. Las nuevas entidades Self-Tracking son creadas en este estado y con Change-Tracking desactivado.

MarkAsDeleted cambia el estado de una entidad a Deleted.

MarkAsModified cambia el estado de una entidad a Modified. Este estado también se obtiene al cambiar el valor de una propiedad en una entidad con Change-Tracking activado.

MarkAsUnchanged cambia el estado de una entidad a Unchanged. También se obtiene este estado al llamar al método AcceptChanges.

  • AcceptChanges

Este método elimina la información de Change-Tracking para una entidad y coloca el estado en Unchanged (es decir, la entidad acepta los cambios que se le realizaron).

Métodos de extensión de ObjectContext

  • ApplyChanges

Examina la información del historial de cambios contenida en el grafo de entidades e infiere el conjunto de operaciones que deben realizarse para reflejar los cambios en la base de datos. Hay dos métodos ApplyChanges, uno para el ObjectContext y otro para el ObjectSet.

Consideraciones para trabajar con entidades Self-Tracking

Finalmente, para cerrar, les dejo algunas consideraciones a tener muy en cuenta antes de utilizar este tipo de entidades:

  • Al enviar un grafo modificado a un servicio, y luego intentar continuar trabajando con el el grafo modificado en el cliente, se debe iterar manualmente por el grafo en el cliente y llamar a AcceptChanges en cada objeto para resetear el Change-Tracking.

  • Las entidades Self-Tracking no permiten realizar Lazy Loading.

  • La serialización Binaria y la serialización a objetos de administración de estados ASP.NET no es soportada por el código generado por los templates de ADO.NET Self-Tracking Entity Generator, para soportala se debe agregar el código necesario al template.

Fuentes:

Tags: ,

ADO.NET | Entity Framework | Visual Studio

Comentarios (2) -

02/09/2010 22:40:12 #

Juanma

Excelente!

Juanma | Responder

01/10/2010 4:42:32 #

cesar

Maginífica explicación. Ahora conozco mejor las desventajas de cada uno.
Una pregunta:
Tengo mi proyecto en capas y orientado a componentes, lo cual fantástico. Pero para proyectos pequeños y bajo el mismo entorno ¿no sería mejor escoger las entidades autogeneradas (EntityObject) a pesar de la dependencia? Total, si algún día cambia el Framework, estoy seguro que los conceptos de Lazy Loading y Self Tracking seguirán ahí, pues no son nada nuevo.

cesar | Responder

Agregar comentario

  Country flag

biuquote
  • Comentario
  • Vista previa
Loading

Acerca de los Autores

Este es el blog del equipo de VEMN SA 
Presentaremos temas que nos parezcan de interés sobre tecnología .NET, Procesos y Metodologías y todo aquello relacionado con el proceso de desarrollo de Software

Month List

BlogRoll

Download OPML file OPML