Valores por defecto de entidades
Hemos añadido una nueva característica a Nibi.Negocio que vamos a deshabilitar hasta perfeccionarla. La idea es tener valores por defecto en las propiedades de una entidad, de forma que esos valores no se guarden en la persistencia. Por ejemplo, si tenemos una propiedad Idioma en una Persona, podemos establecer que su valor por defecto sea el Idioma del País de dicha Persona. Al guardar, si una Persona tiene como Idioma el de su País, guardaremos null, y al cargar si encontramos null usaremos el Idioma de su País. Obviamente al trabajar con valores por defecto en una propiedad eliminamos la posibilidad de guardar valores nulos.
Como primera solución decidimos crear un método virtual en las entidades para sobrecargarlo en aquellas que tengan valores por defecto, devolviendo dicho valor. Este valor se utiliza al cargar la entidad (si una propiedad trae null se establece su valor por defecto) y al guardarla (si su valor coincide con el valor por defecto, se graba un null).
Pero nos encontramos con un problema: el momento del cálculo del valor por defecto. Estos valores normalmente son extraídos de las entidades, por lo que suelen necesitar una consulta a la base de datos. Si mientras estamos en una transa y cargando un objeto necesitamos obtener un valor por defecto (y es lo normal para completar su carga), esto fuerza una nueva carga de un objeto anidada en la primera, y la transa hace que trabajen con la misma conexión, la cual ya está asociada a un DataReader y no puede volver a usarse, devolviendo el error "Ya hay un DataReader abierto asociado a este comando, debe cerrarlo primero."
Posibles soluciones:
- Adelantar la carga de los valores por defecto antes de comenzar la transa. Es muy difícil por no decir imposible saber qué propiedades habrá que cargar en la transa, puede estar anidada muy profundamente y sería demasiado tedioso prever esto.
- Atrasar la carga de los valores por defecto hasta terminar la carga del objeto (hasta que termine de usarse el DataReader). Esto es más viable, aunque tiene un problema: mientras se está cargando el objeto es inconsistente (aún no está cargado completamente). Para la carga de un sólo objeto puede no tener importancia, pero si estamos cargando una colección, y además de forma asíncrona, hasta no terminar con la carga de la colección no se libera el DataReader, por lo que no podríamos establecer los valores por defecto a las propiedades de los objetos que lo requieran.
- Utilizar otra conexión para la obtención de los valores por defecto, es decir, trabajar al margen de la transa. Esto podría ser peligroso al devolver valores antiguos (anteriores a la transa), pero podría funcionar, y parece la solución más sencilla.
- Actualmente estamos usando dos propiedades para los valores por defecto, una persistente (Idioma) y otra calculada (IdiomaAplicable) que es la que considera el valor por defecto. La única pega es ofrecer 2 propiedades donde realmente sólo se necesita una. Pero tiene la ventaja de que sólo se obtiene el valor por defecto cuando el usuario quiere ver o modificar la propiedad, no al cargar y guardar el objeto.
- Profundizando en la idea anterior, podría mantenerse el valor persistente tal cómo se lee, y cuando el usuario quiera el valor de la propiedad, comprobar con el valor por defecto y devolver el apropiado. Cuando se establezca un valor, hacer lo propio. Este valor persistente debería guardarlo EBase, para que la propiedad de negocio sea idéntica a una que no tenga valor por defecto (más sencillo para el usuario).
Lo que vamos a hacer ahora es quitar el uso de la propiedad por defecto ya que está fallando, y volver a las 2 propiedades (solución 4), y cuando nos decidamos por una de estas alternativas os lo haremos saber.
Etiquetas: Nibi.Negocio

0 Comments:
Publicar un comentario
<< Home