Ver Mensaje Individual
  #5  
Antiguo 12-11-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por alquimista_gdl Ver Mensaje
opté por separar los dataset Meastro y Detalle, cada uno con su Provider; los relacionoa pata" vía código, y ahora al oprimir el botón de "Cambiar", sale el error "Key violation"
Me es familiar este error cuando se establecen dos TClientDataSet en relación maestro-detalle y dicha relación, en lugar de ser uno a muchos, es muchos a muchos. Tiene que ver con la bandera pfInkey establecida en la propiedad ProviderFlags del campo de llave primaria de la tabla detalle.

Sucede que cuando cambias de registro maestro, los actuales registros detalles no se eliminan de la memoria del conjunto de datos, sino que se esconden, para dar paso a los registros detalles correspondientes al registro maestro seleccionado. Este mecanismo evita que vuelva a consultarse la base de datos si el usuario regresa al anterior registro maestro, pues sus correspondientes registros detalles fueron cargados en memoria anteriormente.

El inconveniente de este mecanismo es que no se permite que existan en memoria dos registros con la misma llave primaria, lo cual es bastante razonable, considerando que lo habitual de las relaciones maestro-detalle es que sean de tipo uno a muchos. Cuando son de tipo muchos a muchos, ocurre que un mismo registro puede cargarse dos o más veces en la memoria del conjunto de datos detalle (una copia por cada registro maestro asociado en donde haya estado el conjunto de datos maestro). Pero para que esto funcione, se necesita que no haya campo alguno, en el conjunto de datos detalle, con la bandera pfInKey (solución no siempre conveniente), o bien, limpiar con el método EmptyDataSet la memoria del conjunto de datos detalle justo antes de que ocurra navegación en el registro maestro. La desventaja de esta segunda opción es que se estará haciendo una lectura a la base de datos (de registros detalles) cada vez que se mueva de fila el conjunto de datos maestro —aunque se trate de una fila donde haya estado antes—

Por otro lado, no respondiste a mis dos preguntas iniciales. Personalmente no acostumbro usar los conjuntos de datos anidados, pues por lo general me resulta más práctico establecer las relaciones maestro-detalle en el lado cliente (similar a como tú lo has hecho ahora), pero podría valer la pena seguir intentándolo como lo planteaste al principio, investigando un poco más y realizando puntuales pruebas al respecto.

Seguimos de cerca.

Al González.

P.D. No había visto tu último mensaje, donde mencionas lo del campo llave, y que esencialmente es lo que expliqué arriba.

Última edición por Al González fecha: 12-11-2009 a las 18:56:04.
Responder Con Cita