5

Jul

MCTS 70-516: Accesso ai dati tramite .NET 4! Parte 1

Ciao a tutti,

 

siccome  sto studiando questo libro (http://www.hoepli.it/libro/accessing-data-with-microsoft-net-framework-4-mcts-exam-70-516/9780735627390.asp) per conseguire la certificazione 70-516 , ho deciso di fare un riassunto per ogni lezione, su questo blog, in modo tale da poter aiutare chi volesse approfondire questo campo.

Spero di essere il più chiaro possibile, comunque per qualsiasi problema contattatemi Occhiolino.

In questo capitolo parleremo delle classi disconnesse che ci offre Ado.NET e come poterle utilizzare al meglio.

Nella prima lezione vedremo come lavorare con gli oggetto DataTable e DataSet.

Questi oggetti fanno parte delle “Classi disconnesse” perché possono essere usate senza dover creare una connessione al data store. L’assemby dove vengono implementate queste classi è il System.data.dll e sono raggiungibili tramite il namespace System.data .

 

Parte 1:  Datatable

Un oggetto DataTable è composto da righe e colonne proprio come una tabella. Per creare un datatable si può utilizzare la seguente sintassi

//Creiamo un datatable con il nome pippo

DataTable dtPippo = new DataTable(“pippo”);

 

Come si vede nel codice precedente, passiamo come parametro al costruttore il nome che vogliamo utilizzare per la tabella. Dopo la creazione, come prima cosa, dobbiamo aggiungere delle colonne per poter iniziare a creare lo schema del nostro datatable e avere una maggiore integrità sui dati. Per aggiungerle si usa l’oggetto DataColumn come mostrato nell’esempio:

 

//Aggiungiamo una nuova colonna

DataColumn name= new DataColumn(“name”);   //Creiamo la colonna e gli assegniamo il nome ‘name’

name.DataType = typeof(string); // gli impostiamo che la colonna è di tipo stringa

name.MaxLenght = 20; // numero massimo di caratteri ammessi

name.AllowDBNull = false // impostiamo che questo campo non può essere null

name.Unique = false // abilita o meno l’esistenza di duplicati nella stessa colonna

dtPippo.Columns.Add(name); // aggiungiamo la colonna al nostro datatable

 

DataColumn id= new DataColumn(“id”);   //Creiamo la colonna e gli assegniamo il nome ‘name’

id.DataType = typeof(int); // gli impostiamo che la colonna è di tipo stringa

id.MaxLenght = 20; // numero massimo di caratteri ammessi

id.AllowDBNull = false // impostiamo che questo campo non può essere null

id.Unique = true // abilita o meno l’esistenza di duplicati nella stessa colonna

dtPippo.Columns.Add(id); // aggiungiamo la colonna al nostro datatable

 

L’oggetto DataColumn ha vari overloads dei costruttori che permettono di creare una colonna con una semplice riga di codice. Per creare una tabella in maniera corretta bisogna impostare una colonna come Primary Key. Queste possono essere varie, infatti la proprietà accetta un array di datacolums:

 

dtPippo.PrimaryKey = new DataColumn[]{id};

Proprio come in un database possiamo settare un autoincrement alle colonne chiave. Per impostare questo comportamento dobbiamo settare la proprietà autoincrement = true, l’autoincrementseed = –1 e l’autoincrementstep = –1. Si impostano i numeri negativi per evitare che questi numeri vadano in conflitto con quelli ricevuti dal database.

 

Parte 2: DataRow

 

Una volta creato lo schema del nostro DataTable, avremo la necessità di dover aggiungere dei dati al suo interno. Per fare ciò si utilizza l’oggetto DataRow e si istanzia con la seguente riga

DataRow dr = dtPippo.NewRow();

 

L’oggetto DataTable contiene la proprietà Rows che è di tipo DataRowCollection e contiene i vari oggetti DataRow. DataRowCollection espone un metodo Add che accetta un oggetto DataRow e server per aggiungere una riga creata da noi alla collection di righe del datatable. Vediamo il codice che ci serve per creare una riga ed aggiungerla al datatable:

DataRow dr = dtPippo.NewRow();

dr[“nome”] = “Carmine”;

dt.Rows.Add(dr);

Ogni DataRow ha una serie di stati che possono essere visualizzati e filtrati e sono:

Detached: Il datarow è stato creato ma non è stato aggiunto al datatable

Added: Il datarow è stato creato e aggiunto al datatable

Unchanged: Il datarow non è stato modificato dall’ultima chiamata al metodo AcceptChanges

Modifield: Il datarow è stato modificato dall’ultima chiamata al metodo AcceptChanges

Deleted: il datarow è stato segnato per essere cancellato quando verrà chiamato il metodo DataRow.DeleteRow.

 

Ogni DataRow contiene al suo interno tre versioni dei dati:

Current: sono i valori correnti della riga. Questo versione è presente in tutte le situazioni.

Original: sono i valori originali che non possono essere modificati.

Proposed: sono i nuovi valori proposti in modalità di modifica della riga prima di effettuare il salvataggio.

 

L’oggetto DataRow contiene un metodo chiamato HasVersion che può chiedere l’esistenza di una particolare versione del datarow.

Una volta modifiche le nostre righe dobbiamo persistere i vari cambiamenti. Il metodo che fa a caso nostro è AcceptChanges. Questo metodo è implementato dagli oggetto DataRow, DataTable e DataSet. Una volta effettuato il salvataggio, i dati in proposed passano in current e se questa è la prima modifica quelli in current passeranno nella versione original. Un altro metodo molto utile è RejectChanges che ci permette di riportare i dati modificati allo step precedente! Una cosa importante da ricordare è di chiamare sempre il metodo AcceptChanges dopo aver modificato con successo i dati nel database in modo tale da impostare tutte le righe del nostro datatable in Unchanged e di conseguenza avere una corretta sincronizzazione con il database. Per eliminare una riga bisogna utilizzare il metodo Delete esposto da DataRow. Questo metodo non fa altro che cambiare lo stato della riga in Deleted senza però cancellarla subito, l’effettiva eliminazione avverrà quando chiameremo il metodo AcceptChanges. Una cosa importante da sapere è che non esiste un metodo Undelete, quindi se vogliamo recuperare una riga segnata come Deleted dobbiamo chiamare il metodo RejectChanges.

Per avere una copia del nostro datatable esistono due modi: Il primo è chiamare il metodo Copy che copia interamente il nostro datatable compreso lo schema e i dati:

DataTable newDt = dtPippo.Copy();

Se invece non abbiamo bisogno dei dati ma soltanto dello schema possiamo utilizzare il metodo Clone() sempre esposto dall’oggetto DataTable. Dopo aver clonato il nostro DataTable, possiamo aver bisogno di dover importare determinati oggetti DataRow. L’oggetto DataTable contiene il metodo ImportRow che serve proprio a questo scopo:

DataTable clone = dtPippo.Clone();

clone.ImportRow(dtPippo.Rows[0]);

in questo modo la prima riga della tabella dtPippo verrà copiata nella nostra nuova tabella.

Parte 3: DataView

Una volta creata e popolata la nostra tabella .Net ci offre la possibilità, tramite l’oggetto DataView, di filtrare e ordinare i dati per una determinata ricerca per poi visualizzarli a video. Per esempio, se vogliamo ordinare per nome la nostra tabella possiamo utilizzare questo codice:

DataView dv = new DataView(dtPippo);

dv.Sort = “nameASC”;

Se invece volessimo filtrare i risultati solo per i nomi che iniziano con la c:

dv.RowFilter = “name like ‘C%’”;

La proprietà RowFilter  è uguale alla clausola WHERE di SQL.

Parte 4: DataSet

I DataSet, concettualmente, sono dei Database che possono contenere varie tabelle ed assegnare i vari vincoli relazionali. La creazione del dataset è molto semplice:

 

DataSet dsPluto = new DataSet(“DatabasePluto”); //creo l’istanza del dataset

DataTable dtPippo = dsPluto.Tables.Add(“dtPippo”); //Aggiungo una nuova tabella al dataset

… // creo la mia tabella come sopra

DataTable dtPaperino = dsPluto.Tables.Add(“dtPaperino ”); //Aggiungo una nuova tabella al dataset

… // implemento la mia tabella

 

Se ora volessimo relazionare le due tabelle dovremmo utilizzare questo metodo esposto dall’oggetto DataSet:

dsPluto.Relations.Add(“nome_della_relazione”, colonna_della_prima_tabella, colonna_della_seconda_tabella);

In questo modo creiamo un vincolo tra le tabelle proprio come facciamo durante la creazione di un database.Da questo momento i “dati figli” non potranno essere aggiunti se non sono collegati ad un “dato padre”. Come esempio più pratico si pensi agli ordini (dati padre) che contengono in un altra tabella i vari dettagli(dati figli). Per mantenere una maggiore integrità dei dati, quando vogliamo eliminare una riga padre, dobbiamo eliminare tutte le righe figlie! Per fare questo dobbiamo settare la proprietà DeleteRule dell’oggetto ForeignKeyConstraint su Cascade:

ForeignKeyConstraint  fk = (ForeignKeyConstraint) name.Constraints[“nome_della_relazione”];

fk.DeleteRule = Rule.Cascade;

 

Questa regola vale naturalmente anche per l’update dei dati, se si ha la necessità di aggiornare il dato della chiave di relazione è opportuno modificarla anche negli elementi figli!

 

Per questa prima lezione è tutto… per qualsiasi problema, perplessità, correzione o dubbio contattatemi senza problemi.

Nella prossima lezione parleremo di come Serializzare e Deserializzare i DataTable con XML Data.

 

Buona giornata

A presto

Carmine Punella

by Carmine Punella on 7/5/2011
Post archive