16

Aug

Aggiornamenti gerarchici automatici con DataSet e TableAdapterManager in ASP.NET

Ciao a tutti

approfitto della pausa estiva per scrivere un po di cose utili per chi usa i DataSet

Come sappiamo un DataSet è una copia del nostro DB, al suo interno ci possono essere varie copie delle nostre tabelle (DataTable) collegate tra di loro con le relative relazioni (DataRelation).

Uno scenario tipico è la necessità di aggiornare una coppia di tabelle (fattura, elementi fattura; ordini, dettaglio ordine; etc.) in un'unica soluzione, diciamo pure con un unico click.

Il dataset designer del VS2008SP1 ci offre una interessante funzionalità: il TableAdapterManager. Questo è un tableadapter aggiuntivo che viene scritto per noi dal designer quando creiamo un DataSet tipizzato, in aggiunta ai consueti TableAdapter per ogni DataTable che abbiamo aggiunto al nostro DataSet. Il nuovo TableAdapterManager è un tableadapter centralizzato per gestire al posto nostro gli Update in modo gerarchico.

Facciamo degli esempi:

Aggiungiamo una relazione tra due tabelle sul DB

Creiamo un DataSet tipizzato aggiungendo le due tabelle da noi create, questo aggiungerà anche la relazione in automatico.

Clicchiamo destro sulla relazione e editiamola settando: "Both relation and foreign key constraint", update e delete rule a "update".
Questo ci serve per dire al designer di rendere gerarchica la gestione delle modifiche sulle righe della tabella padre verso la figlia.

Ultima cosa importante: facciamo click sul TableAdapter che il designer disegna sotto la tabella "padre", e editiamone il CommandText dell'InsertCommand.
Il designer in automatico ha scritto la INSERT al posto nostro, ma non ha scritto la rilettura dei dati (da cui arriverà la nuova chiave che il DB andrà a generare per la nostra riga).
Per farlo aggiungiamo alla query di INSERT una seconda query in basso così:

INSERT INTO Table1(a,b,c, etc...) SELECT @a,@b,@c, etc... ;
SELECT * FROM Table1 WHERE ID=@@IDENTITY questa è una funzione di SQL Server per darci il valore della colonna autogenerata (l'incrementale)

Adesso scriviamo:

[code language="csharp"]
TableAdaptermanager tam = new TableAdapterManager();
tam.Table1TableAdapter = new Table1TableAdapter();
tam.Table2TableAdapter = new Table2TableAdapter();
[/code]

Adesso abbiamo creato un adapter centralizzato in cui abbiamo inizializzato gli adapter delle singole tabelle

[code language="csharp"]
DataSet1 ds = new DataSet1();
tam.Table1TableAdapter.Fill(ds.Table1); // E' importante fare il "fill" dei dati (e non il get) nel giusto ordine, dal padre al figlio.
tam.Table2TableAdapter.Fill(ds.Table2);
[/code]

modifichiamo una riga e una sua child

[code language="csharp"]
ds.Table1[0].Name='pippo';
ds.Table1[0].GetTable2Rows()[0].Value='valore modificato';
tam.UpdateAll(ds);//per fare un singolo update, basta scrivere
[/code]

by Antonio Esposito on 8/16/2010