Object ID en EF 4.1

Hola

Hace poco me he comprado el excelente libro de Entity Framework 4.1. He leído mucho sobre este ORM desde sus primeras versiones, pero nunca me resultó lo suficientemente atractivo para usar en un proyecto real sobre el cual me permitieran elegir. Como alternativa a EF tenía NHibernate, ORM que también he usado desde hace mucho tiempo y sobre el cual no tengo dudas en cuanto a funcionalidad o limitaciones que me pueda encontrar.

Entendiendo que no siempre se puede elegir, y por los muchos comentarios que ha generado la nueva versión de EF 4.1 (y más por la posibilidad real de no tener atadas las entidades al ORM) decidí de una vez enfrentarme a él de manera seria, pero es inevitable hacer comparaciones (aunque no sean buenas) 

Aclaro que mi intención jamás sería, ni por asomo, criticar a este excelente ORM, más bien esta serie de artículos va por el camino de conocer bien hasta dónde llegan mis limitaciones en su utilización.

Los Object ID.

Desde cualquier aplicación orientada al dominio se enfoca mucho la necesidad, que yo llamaría obligación, de empezar siempre por el modelo. Es imposible no acordarme de la forma en que casi se suplica en el libro de EF 4.1 (Pág. 78) cuando dice: – “Primero el modelo por favor”.  🙂

Siguiendo tan buen consejo me voy a Visual Studio dispuesto a seguir el ejemplo descrito en el libro empezando por la entidad  “Autor”.

Me detengo en esta ventana en la que remarco la propiedad “Key Property”. ¿Qué significa esto desde el punto de vista del modelo? Pues si estoy pensando en el modelo esta propiedad representa entonces el Object ID de la entidad.

La definición de Object ID está explicada en Mapping Objects To Relational Databases de Scott W. Amble.

We need to assign unique identifiers to our objects so that we can identify them. In relational terminology a unique identifier is called a key, in object terminology it is called an object identifier (OID) although perhaps persistent object identifier would be a better term. OIDs are typically implemented as full-fledged objects in your OO applications and as large integers, or several large integers for larger applications, in your relational schema

Yo creo que la definición ni siquiera necesita traducción 🙂

Algunas funcionalidades de los OID coinciden con su “homólogo” en el modelo relacional. Por ejemplo, mantener y simplificar la relación entre entidades (joins entre tablas en el modelo relacional). Uno de los errores más comunes cuando definimos el modelo es cuando asignamos una responsabilidad al OID dentro del dominio. Los OID NO pueden tener ningún significado lógico “Nada, Zip, Zilch, Zero”  😛 Como dice Scott, toda propiedad que interviene en un modelo con un significado dentro del dominio puede ser potencialmente cambiada. Un OID, no.

Regresando a EF 4.1 (que me pierdo) creo mi entidad y me decido a seleccionar mi estrategia para el OID dentro del modelo.

 

Pues vaya sorpresa :”( solo tengo 3 opciones como estrategia para generar mi OID. ¿Cuál de estas tres opciones puedo elegir?

MSDN dice:

Computed – Un valor generado para INSERT y para UPDATE. o_0  No me he puesto a pensar en qué casos me puede ser útil esta estrategia, ahora mismo no me imagino ninguna porque si el OID cambia durante su ciclo de vida, rompe con su condición de ser único e invariable.

Identity – Un valor que es generado durante el INSERT y que permanece invariable durante las actualizaciones siguientes. Esto es un Identity de SQL en toda regla. ¿Por qué el identity de SQL no es para mí una estrategia válida? Pues Scott lo deja claro cuando dice “An OID should be unique within a class hierarchy, and ideally unique among all objects”

El identity puede generar un mismo valor dentro del modelo para dos entidades distintas y esto rompería también con la definición “ideal” del OID, además, no me vale en absoluto en un sistema distribuido (en un clusters por ejemplo).

None – Generarlo yo implica que tenga que pelearme con el bloqueo de filas para evitar que dos clientes de mi sistema no generen al mismo tiempo un mismo OID. Resultaría tan complejo como se pueda imaginar. Aunque sería la única alternativa y por suerte, hay algoritmos que nos permiten no entrar en polémicas con los bloqueos

NHibernate por su parte propone para los OID las siguientes estrategias : Increment, identity, sequence, hilo(Mi Favorito), seqhilo, uuid.hex, uuid.string, guid, guid.comb, native, assigned y foreign. Las puedes encontrar todas explicadas aquí

Hay que tener en cuenta que NHibernate y EF, trabajan de manera distinta respecto a los OID. NH asegura que se pueda trabajar con el OID de una entidad antes de hacer permanentes los cambios en base de datos, algo muy importante cuando usamos Session per request. Por su parte, EF asegura la unidad dentro del contexto, por lo que no dará el OID hasta que no se guarden los cambios (Si no lo generamos nosotros).

Mi próximo paso en esta serie será ver si puedo crear una estrategia Hi/Lo para usar en EF. La idea del algoritmo Hi/Lo es tener dos valores para formar un único valor. A cada cliente se le asigna un valor Hi y, con un rango de valores Low formaría un identificador único para todo el modelo. Esto garantiza que varios clientes siempre utlizarán valores distintos para los nuevos OID creados y evitaríamos los temas de bloqueos.

¿cómo resuelven esta “limitación” cada uno de los que actualmente usan EF?  😉

3 comentarios en “Object ID en EF 4.1”

  1. Omar, antes de nada, darte las gracias por la mención y las palabras sobre mi libro de EF 4.1. Una vez dicho esto, decirte para para Hi/Lo me acuerdo que jfroma (http://joseoncode.com/) publicó hace un tiempo un ejemplo de uso de este algoritmo de poid en EF, no se si lo ha seguido trabajando/actualizando la verdad. Para guid y guid comb tendrías que implementarte los mecanismos, a mi me gusta guid comb y lo utilizo por medio de un generador en mi dominio directamente..

    Unai

  2. @alfredo.. llegará!! 😉

    @Unai… un placer tenerte por acá 😉 Buscaré y miraré lo que tenga hecho jfroma 🙂 y ya comentaré.. sería un gran adelanto para mi.

    Gracias por los comentarios a los dos 🙂

Deja un comentario

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