Newsgroup: it.comp.lang.delphi
Titolo: Master e Detail

Ciao a tutti, 
ho la seguente configurazione : 
1) qryMaster
2) ProviderMaster  > con dataSet = qryMaster
3) CdsMaster > con ProviderName = ProviderMaster
4) dtsMasterDetail > con DataSet = qryMaster
5) qryDetail > con DataSource = dtsMasterDetail
6) cdsDetail > con DataSetField = CdsMaster.FieldByName('qryDetail')
I componenti Master (dal n° 1 al n° 3) sono su un DataModulo (dmMaster),
i componenti di Dettaglio (dal n° 4 al n° 6) su un altro (dmDetail).
A run-time effettuo le dovute assegnazioni e tutto funziona benissimo.
Il problema è quando ho più di un Detail, poichè ho un unico
datamodulo per gestire il detail (quello di sopra) che instanzio per
ogni tabella di dettaglio.
Logicamente all'attivazione del Master va in errore poichè probabilmente
essendo i 2 dettagli gestiti con lo stesso oggetto SQLQuery cerca di
creare due Field di tipo DataSetField sul Master con lo stesso NOME.
Qualcuno ha qualche consiglio da darmi ?
Ciao 
Rino
p.s. il DBMS è DB2, e logicamente uso la DBExpress (giusto per esseri
chiari)
 

Rino
	Ciao
	MassimoB
 
---------------------------------
http://www.massimobeschi.it/
---------------------------------
Se tu pagare come dici tu ...
Io lavorare come dico io ...
Se tu pagare come dico io ...
Io lavorare come dici tu ...
---------------------------------

 	MassimoB
Grazie.
Ciao 
Rino

dimenticavo, questo è l'errore : 
---------------------------
Debugger Exception Notification
---------------------------
Project GIV2005.exe raised exception class EDatabaseError with message
'clnMaster: Duplicate field name 'qryDetail''.
---------------------------
Break   Continue   Help   
---------------------------

dimenticavo, questo è l'errore : 

bè l'errore è abbastanza esplicito :P quello che non
puoi fare, in caso di più detail, è utilizzare il nome
di un componente come qryDetail, perchè avendo diverse
istanze tale nome rimane identico per ogni istanza,
quello che devi fare è costruirti un nome univoco ...
In un form, cosa deve avere nome diverso? le variabili,
i componenti e sicuramente qualcos'altro ...
puoi utilizzare i nomi dei datamodule per esempio
   >      //Quello per il primo Detail
   >      myField1 := TDataSetField;
   >     with myField1.Create(dmMt.clnMaster) do
   >         begin
   >            Name := 'qryDetail1';
   >            FieldKind := fkData;
               FieldName := dmDt1.Name;
   >            Size := 0;
   >            DataSet := dmMt.clnMaster;
   >         end;
   >      //Quello per il secondo Detail
   >      myField2 := TDataSetField;
   >      with myField2.Create(dmMt.clnMaster) do
   >         begin
   >            Name := 'qryDetail2';
   >            FieldKind := fkData;
               FieldName := dmDt2.Name;
   >            Size := 0;
   >            DataSet := dmMt.clnMaster;
   >         end;
oppure alla creazione del TDMDetail generi un guid
memorizzandolo in una proprietà e lo utilizzi come nome
univoco per il campo
   >      //Quello per il primo Detail
   >      myField1 := TDataSetField;
   >     with myField1.Create(dmMt.clnMaster) do
   >         begin
   >            Name := 'qryDetail1';
   >            FieldKind := fkData;
               FieldName := dmDt1.UniqueIdentifier;
   >            Size := 0;
   >            DataSet := dmMt.clnMaster;
   >         end;
oppure ancora, dai l'incarico alla classe TDMMaster di
gestire una lista con associazioni Campo-DMDetail (puoi
usare una semplice TStrings) in cui ogni TDMDetail si
deve registrare, mediante apposito metodo del
TDMMaster, e alla registrazione gli viene creato un
campo nel dataset con nome univoco ed un'associazione
fra campo e DM nella lista Campo-DMDetail, in maniera
che quando un TDMDetail vuole saper il suo campo,
scorri la lista e quando trovi l'elemento che
corrisponde al TDMDetail chiamante, trovi anche il nome
del campo associato o direttamente l'oggetto campo
associato. Il tutto può essere wrappato da una serie
difunzioni di utilità tipo
DMMaster.FindDataSetFieldByDMDetail(DMDetailChiamante:TDMDetail):
TDataSetField;
DMMaster.RegisterDMDetail(DMDetailChiamante:TDMDetail):
TDataSetField;
ecc
in maniera da racchiudere il codice di basso livello
per l'accesso alla lista (che non vedi dall'esterno) e
non dover fare nemmeno casting a TDataSetField.
Un'altra maniera è, visto che non utilizzi cicli 
dinamici o codice particolare sui nomi dei campi
DataSetField ... vai hardCoded e ti togli il problema.
   >      //Quello per il primo Detail
   >      myField1 := TDataSetField;
   >     with myField1.Create(dmMt.clnMaster) do
   >         begin
   >            Name := 'qryDetail1';
   >            FieldKind := fkData;
               FieldName := 'dmDt1_qryDetail';
   >            Size := 0;
   >            DataSet := dmMt.clnMaster;
   >         end;
tanto che scrivi il nome della variabile o la stringa
il succo non cambia.
Se ho sottovalutato il problema o non ho considerato
altre problematiche chiedo venia è da un pò che non
utilizzo i NestedDataset


Rino


ho gestito la cosa a run-time.
ho create le query di dettaglio a run-time...
Ma non funzionava continuava con l'errore prima descritto...
Allora, preso dai turchi ho fatto un nuovo progetto,  
ho aggiunto tutti gli oggetti che mi servivano sulla form, 
ed a Design-Time quando apro il cdsMaster si alza la stessa eccezione.
Eppure ora le TSQLQuery sono fisicamente 2 oggetti diversi con nome diversi.
Con una sola TSQLQuery funziona tutto, con 2 detail no!
Alchè non mi sono arreso, ho provato su un altro pc dove ho il buon
vecchio delphi6....e come mi apsettavo : "FUNZIONA"....
Ho salvato quel progetto, l'ho portato sulla macchina con D2005 e 
continua a darmi quell'errore....
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EDatabaseError with message
'dbExpress Error: Unknown Error Code '65535''.
---------------------------
Break   Continue   Help   
---------------------------
invece a run-time, se attivo il cds Master prima 
mi da il seguente errore : 
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EDatabaseError with message
'dbExpress Error: [0x0005]: Operation Not Supported'.
---------------------------
Break   Continue   Help   
---------------------------
se faccio continua mi restituisce anche l'errore riscontrato a Design-Time.
A questo punto, una volta appurato che il problema esiste su Delphi2005 e
non su Delphi6 cosa si fa?
Può essere un bug?
Ciao
Rino

ho sostituito la dll DBEXPDB2.DLL di delphi2005 con quella
di Delphi6, e modificando alcune proprietà degli oggetti TSQLQuery,
funziona....
Ma sicuramente non posso lavorare così....
Qualche consiglio?
Ciao
Rino

Continuo nella mia ormai solitaria battaglia.
Ho capito che il problema nasce dal fatto che in una tabella
di dettaglio ci sono campi blob....
Ora, se imposto la proprietà del Provider poFetchDetailsOnDemand = true, e/o 
la proprietà poFetchBlobsOnDemand = true, riesco a reperire i dati sia del cds
Master che dei 
due Detail....
Ma non riesco a leggere i fields BLOB (che poi è uno solo)....
Qualcuno sà come posso fare?
Ciao 
Rino

Continuo nella mia ormai solitaria battaglia.

hai già provato ha farti un giro sul sito della Borland
per vedere se sono state rilasciate Patch ... io al
tempo scaricai un patch per dbExpress ... ma era per
D6.
Puoi anche provare a postare il problema sul NewsGroup
di DBExpress ora che hai le idee più chiare su quale è
il problema.
borland.public.delphi.database.dbexpress
non so se c'è ne uno più indicato


 	
Ciao 
Rino

che mi hai dato....
Di niente figurati ... in realtà non ti ho dato nessun
consiglio utile al fine di risolvere il problema,
infatti il problema c'è ancora :P
