C'è un piccolo problemino quando si tenta di richiamare il metodo Find di un BindingSource che ha come DataSource una tabella child in una relazione Master/Detail.
Se, ad esempio, abbiamo una tabella Master (parent) così costituita:
Fattura |
ID |
Numero |
Data |
RagioneSociale |
E la relativa tabella Detail (child):
DettFatt |
ID |
IDFattura |
IDArticolo |
Quantita |
Supponiamo ora che volessimo trovare la posizione del record, in DettFatt, con IDArticolo=23, basta fare:
Private Function PosizioneDett(ByVal IDArticolo as integer) as integer
Dim Pos as integer
Pos = Me.DettFattBindingSource.Find("IDArticolo",IDArticolo)
Return Pos
End Sub
Ma c'è un problema.
Se il BindingSource ha come DataSource una DataTable child in una relation, la Find potrebbe non funzionare, sollevando un eccezione del tipo:
"DataMember property 'IDArticolo' cannot be found on the DataSource."
Perchè ho scritto "potrebbe"?
Beh, perchè dipende.
L'errore succede solo se il BindingSource punta direttamente alla DataTable child, per intenderci una tabella che nella visualizzazione ad albero nella Data Sources è figlia di un'altra.
Questo succede tipicamente quando VS crea per noi una BindingSource dopo che abbiamo settato come DataSource di un controllo una tabella child (selezionandola sotto la tabella parent).
Per ovviare a questo problema esiste un workaround: creare un'altro BindingSource che punta direttamente al BindingSource creato da VS.
Forse ci stiamo un po' perdendo, e allora facciamo un esempio:
Creiamo un progetto (ad esempio Windows Form).
Creiamo ovviamente il relativo DataSet, con tanto di relazione tra Fattura e DettFatt (FK_Fattura_DettFatt).
Ora creiamo un primo BindingSource (chiamiamolo FatturaBindingSource) e diamogli come DataSource e DataMember la tabella Fattura del nostro DataSet.
Poi creiamo un altro BindingSource (chiamiamolo DettFattBindingSource) e facciamolo puntare alla
relazione FK_Fattura_DettFatt della
FatturaBindingSource.
Se ora eseguissimo la famosa Find su DettFattBindingSource
otterremo l'errore.
La soluzione è quindi aggiungere un ultimo BindingSource (chiamiamolo
DettFattBindingSource1) e facciamolo puntare direttamente a
DettFattBindingSource.
Se si esegue ora la Find su quest'ultimo BindingSource funziona tutto
correttamente.
Suggerirei poi di rinominare i BindingSource in questo modo:
- DettFattBindingSource diventa
tmpDettFattBindingSource (di fatto è intermedio e non verrà
più utilizzato direttamente da nessun controllo)
- DettFattBindingSource1 diventa
DettFattBindingSource (in questo modo se già avevate
controlli che puntavano al vecchio BindingSource, funziona di nuovo
tutto).
Così si è creato una sorgente dati
(tmpDettFattBindingSource) di livello intermedio, che altro non
fa che fornire dati al BindingSource finale
(DettFattBindingSource) che sarà quello utilizzato dai vari
controlli in DataBind.
powered by IMHO 1.3