db4o: firsts steps
En estos días estuve teniendo mis primeros encontronazos de verdad con db4o, antes habian sido solo pruebas, estoy inscripto al foro hispano oficial, y estuve -para inaugurar- haciendo unas preguntas, que la verdad me sacaron un poco del pozo en el que estaba. Tambien conocí a gente como Alan Lavintman, que me estuvo dando una mano por chat con esta base. Obviamente, yo no podía pasar sin hacer la pregunta que el 90 % de los nuevos que comienzan a usar db4o, viniendo de usar un motor de datos relacional: "como manejo en la inserción la duplicidad de objetos?" ay!...esa pregunta es la del millon!
Este concepto es distinto, no es el mismo que el de un motor relacional, donde se puede manejar una entidad referencial por medio de claves. Por que en una dbms la inserción de los datos en una tabla intermedia -por ejemplo-, se podría implementar por medio de un INSERT INTO y listo, a lo sumo el motor se encargará de lanzar una excepción en el caso de que se viole una regla de integridad, pero no pasa de ahí. Con db4o es muuuuy distinto, creanme, y tiene sus "porques" bien justificados, y no porque db4o lo justifique, es que hablando de objetos...no podría ser de otra forma.
Vean esto, tengo dos clases, A y B, despues tengo una clase C (que vendría a ser si se quiere, como una "tabla intermedia"), en este caso seria un objeto que tiene relación con los otros dos objetos (A y B), en UML sería visto como una asociación como clase. Ahora, seamos un poco creativos, e imaginemos que tenemos que no tenemos la necesidad de guardar los objetos, por que nuestra memoria es no-volatil y no tengo problemas de capacidad de memoria (ni de velocidad si se quiere), de modo que tengo todos los objetos en memoria, y en vez de insertar, tengo que asociarlos nada más. Entonces tendré que tener en la mano el objeto del tipo C (es el nuevo objeto) y tambien los objetos del tipo A y B para asociarlos. De modo que podriamos ver que la clase de C tendría una propiedad de tipo A y otra propiedad de tipo B (minimamente), tambien podría tener otros atributos, por ejemplo Descripcion.
La clase C podría declararse así:
public class C
{
private A _A;
private B _B;
private string _Descripcion;
public A A
{
get { return _A; }
set { _A = value; }
}
public B B
{
get { return _B; }
set { _B = value; }
}
public string Descripcion
{
get { return _Descripcion; }
set { _Descripcion = value; }
}
}
Ahora tendriamos que setear las propiedades de C:
[...]
C ObjC = new C();
ObjC.A = objA;
ObjC.B = objB;
ObjC.Descripcion = "Esto es una descripcion";
[...]
...y así estariamos realizando la asociacion de dichos objetos.
Ahora olvidando el concepto de object prevalence (que hablando rapido es: tener todos los objetos en memoria -bien básico-) y volviendo a la realidad... volviendo a nuestra db4o, para tener que hacer una inserción de un objeto que tiene una asociacion con otros objetos, tenemos que:
1) Cargar primeramente los otros objetos.
2) Asociar los objetos, -seteando los campos del objeto a insertar-.
3) Guardar el nuevo objeto en la base.
4) Listo, objeto y las referencias ya se han realizado.
Otra cosa que me pareció interesante destacar, que a db4o le importa muy poco como sobreescribamos los metodos Equals, no realiza comparaciones con él.
Tambien puede ser de ayuda, el concepto de callbacks, que db4o implementa. Son funciones que se disparan cuando ocurren ciertos eventos.
Por ejemplo, está el callback ObjectCanNew que devuelve un bool, y se dispara cada vez que se está por insertar un nuevo objeto, si el resultado de la función devuelve true, se guarda el objeto, de lo contrario no. En esa función tendríamos que agregar el procedimiento de validación.
Pero este concepto intrusivo de db4object, particularmente no me gusta mucho, por que tenemos que decorar todas nuestras entidades de negocio con estos metodos.. que son parte del acceso a datos, y poco tiene que hacer en cuanto a una validación de negocios. Pero...es una opción.