BindingSource.Find con sorgente child

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 integeras 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

Print | posted @ Wednesday, March 22, 2006 12:52 PM

Comments have been closed on this topic.