27.06.2014 Views

INFORMATICA MEDICA

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>INFORMATICA</strong> <strong>MEDICA</strong><br />

7. Accesso ai dati<br />

Prof. Mauro Giacomini


Sommario<br />

• Proprietà e metodi dei seguenti oggetti<br />

• DataReader<br />

• DataAdapter<br />

• DataTable<br />

• DataSet<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataReader: caratteristiche<br />

• Contiene<br />

• solo una struttura dati alla volta (il risultato di un’unica query)<br />

• i valori di un solo record alla volta<br />

• Solo lettura sequenziale<br />

• no ordinamento<br />

• no accesso casuale<br />

• no cambiamento dei valori nei DB<br />

• Lettura solo connessa<br />

• Ottimizzazione elevata<br />

• Tre tipi per i 3 diversi data provider<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


SqlDataReader: Confronti<br />

• Protocollo di comunicazione col server proprio<br />

dei client di SqlServer Tabular Data Stream<br />

(TDS)<br />

• Assenza di provider intermedi<br />

• Metodi di accesso ai dati che restituiscono i<br />

datatype nativi di SQL Server: minimizzazione<br />

delle perdite di precisione<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Creazione del DataReader<br />

• Importazione del namespace<br />

• Dichiarazione<br />

• Item: proprietà che restituisce il valore di una<br />

colonna del record dei dati estratti<br />

• Colonna specificata con il nome (nome del campo della<br />

tabella o alias pubblicato nella query) o la posizione<br />

ordinale nel record (si parte da 0)<br />

• FieldCount: proprietà che restituisce il numero dei<br />

campi del record corrente.<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataReader: metodi (1)<br />

• Ottiene i dati con il metodo ExecuteReader dell’oggetto Command<br />

• DataReader non contiene i dati estratti, ne consente solo la lettura con il<br />

metodo Read<br />

• Si deve sempre invocare il metodo Read all’inizio per generare il<br />

puntatore ai dati<br />

• Se la lettura ha dato esito positivo il valore di Read è true<br />

• Si legge in un loop da cui si esce quando Read restituisce false<br />

• Close: metodo di chiusura della connessione e dell’oggetto DataReader<br />

stesso<br />

• Chiusura automatica gestita dalla proprietà CommandBehaviour<br />

• GetName: restituisce una stringa contenente il nome della colonna<br />

(indicata con la posizione ordinale), serve per le intestazioni delle tabelle<br />

• GetOrdinal: restituisce un numero indicante la posizione della colonna<br />

all’interno del record (indicata con il nome del campo)<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Esempio: commenti<br />

• Estrazione dei dati da visualizzare<br />

• Generazione della stringa SQL<br />

• Uso di procedura esterna<br />

• Lettura in un ciclo While<br />

• Identificazione del primo record<br />

• Scrittura dell’intestazione dei dati stessi con un<br />

ciclo For<br />

• Scrittura del contenuto dei campi stessi con un<br />

altro ciclo for più esterno, usando la proprietà item<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Uso del DataReader: Esempio<br />

• Caricamento di oggetti visuali come ListBox e ComboBox<br />

• Scopo: leggere tutti i record di una tabella e metterne in<br />

nomi nel controllo di tipo lista (vedi routine CaricaListBox)<br />

con il metodo Add della collection Items della lista stessa<br />

• Questa Routine deve essere chiamata dall’evento load della<br />

form<br />

• Gli oggetti di tipo lista possono contenere nella lista degli<br />

items oggetti più complessi del solo nome<br />

• La struttura degli item può essere definita con apposite<br />

classi<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Definizione delle classi<br />

• Selezionare AddClass dal menu progetto, specificandone il<br />

nome<br />

• Vedi listato di definizione delle classi<br />

• Una proprietà per ogni informazione di dettaglio che si vuole<br />

gestire<br />

• Classe Generale per un oggetto numerico con descrizione<br />

alfanumerica, con due proprietà:<br />

• IdOggetto: codice numerico<br />

• NomeOggetto: descrizione dell’oggetto<br />

• Usata per caricare le ComboBox dei fornitori e delle categorie<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Definizione delle classi:<br />

Esempio (VB)<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Definizione delle classi:<br />

Esempio (C#)<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Caricamento della ListBox<br />

• SQL più articolata per valorizzare la classe<br />

• Per ogni record è creato un nuovo oggetto istanziando la<br />

classe, le cui proprietà sono valorizzate leggendo la<br />

proprietà Item dell’oggetto DataReader<br />

• Si aggiunge il prodotto alla lista con il metodo Add della<br />

collezione Items della lista<br />

• Quello che si vede nella lista è determinato dalla funzione<br />

ToString della classe invocata all’atto della valorizzazione<br />

della proprietà, la sua ridefinizione nella classe fa sì che la<br />

proprietà indicata sovrascriva tutte le altre in fase di<br />

visualizzazione<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Caricamento delle ComboBox<br />

• Si usano istanze della classe clsOggettoNum<br />

• Vedi il listato di esempio<br />

• Per ogni record è creato un oggetto della classe le cui<br />

proprietà sono valorizzate con gli item del record stesso<br />

• Si aggiunge l’oggetto agli item della ComboBox<br />

• Anche qui una proprietà sovrascrive le altre in fase di<br />

visualizzazione<br />

• Tutte queste procedure devono essere eseguite durante il<br />

load della form<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Visualizzazione (1)<br />

• Scopo: popolare gli oggetti con i dettagli<br />

dell’Item selezionato<br />

• Nelle TextBox basta l’assegnazione diretta<br />

• Nelle ComboBox va individuato il valore al loro<br />

interno (vedi listato: CercaItemInCombo). Alla<br />

routine si passa l’oggetto in cui cercare (byRef<br />

modificabile) e l’id da cercare (byVal<br />

immodificable)<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Visualizzazione (2)<br />

• Scopo caricare i dettagli nella form<br />

• Vedi listato CaricaFormCollection<br />

• Generazione dell’oggetto di tipo classe indicato con<br />

l’istruzione CType che converte un oggetto che appartiene<br />

alla collezione degli item della lista in un oggetto della classe<br />

indicata.<br />

• Le proprietà di questo oggetto popolano i record o<br />

direttamente o con la subroutine vista prima<br />

• Questa visualizzazione deve essere innescata dall’evento<br />

SelectedIndexChanged della lista dei prodotti<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Sequenza di esecuzione<br />

• Alla load sono chiamate le routine di<br />

caricamento di fornitori, categorie e alla fine dei<br />

prodotti<br />

• Quando sono caricati tutti i prodotti la selezione<br />

automatica del primo prodotto della lista fa<br />

scattare l’evento SelectedIndexChanged così<br />

anche gli altri controlli sono caricati<br />

correttamente<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Modifiche: Aggiornamento<br />

• Creare un nuovo oggetto di tipo classe indicto<br />

• Popolare le proprietà con i nuovi valori digitati negli oggetti<br />

• Eseguire una query di update<br />

• Vedi listato di esempio per la popolazione delle proprietà dell’oggetto classe<br />

indicato<br />

• Di nuovo si usa CType<br />

• Vedi listato di esempio per la scrittura della tabella<br />

• Scrive i parametri della query di update dalle proprietà dell’oggetto classe<br />

indicato<br />

• Chiama la procedura EseguiWriteParametrica<br />

• L’aggiornamento è eseguito alla pressione del tasto aggiorna. Vedi listato:<br />

btnAggiorna_Click<br />

• Dopo l’aggiornamento si deve ricaricare la lista dei prodotti<br />

• Selezionare di nuovo il prodotto modificato per vedere se le modifiche sono state<br />

registrate<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataTable – DataColumn (1)<br />

• Contenitore di memoria strutturato in modo del tutto simile<br />

alla tabella di un DB. Non dipende dal DBMS interfacciato.<br />

• Creazione esplicita con il comando new<br />

• Proprietà TableName: nome univoco<br />

• Definizione dei campi che compongono il record: oggetto<br />

DataColumn<br />

• Columns: Proprietà di tipo collection che contiene i campi fra<br />

i quali coloro che costituiscono la chiave primaria<br />

• Creazione esplicita con il comando new<br />

• Proprietà ColumnName: nome univoco in ogni tabella<br />

• Proprietà DataType: ottenuta con il metodo GetType<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataColumn (2)<br />

• Possibilità di definire dei vincoli con le proprietà<br />

booleane<br />

• Unique<br />

• AllowDBNull<br />

• La tabella ha una collezione di colonne Columns a<br />

cui la colonna definita e completata può essere<br />

aggiunta con il metodo Add<br />

• Possibile definire una lunghezza massima<br />

MaxLength<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataRow<br />

• Definizione ed assegnazione ad una<br />

DataTable per indicarne la struttura<br />

• Accoglie i record da gestire, con la<br />

valorizzazione di tutti i campi<br />

• Quando tutti i campi obbligatori hanno valore<br />

si inserisce la riga nella collezione Rows della<br />

tabella con il comando Add<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataAdapter<br />

• Fornisce più funzionalità rispetto a DataReader<br />

• Indicato per estrarre dati da manipolare<br />

• Dipende dal particolare DBMS<br />

• Creazione con New<br />

• Necessita di:<br />

• Comando Valido<br />

• Connessione attiva<br />

• È possibile sia associare a un DataAdapter il comando e la connessione<br />

in due modi<br />

• Associando dei comandi e delle connessioni precedentemente definite<br />

• Passando all’atto della istanziazione due parametri: la stringa di SQL e la<br />

stringa di connessione, in questo secondo caso la connessione sarà<br />

completamente gestita dal DataAdapter<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataAdapter e DataTable<br />

• Il metodo Fill riempe un DataTable di cui non si deve<br />

neppure definire la struttura<br />

• Tale tabella rimane in memoria, svincolata dalla conessione<br />

e possiamo scorrerla a piacimento evitando le limitazioni che<br />

avevamo con il DataReader.<br />

• Vedi listato: CaricaListBoxDataTable<br />

• Si scorrono tutte le Row del DataTable e per ogni row si<br />

genera un oggetto del tipo classe indicato<br />

• Anche le ComboBox possono essere riempite con<br />

DataAdapter e DataTable, vedi listato: di esempio<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


DataSet<br />

• DataSet: contenitore di oggetti di tipo<br />

DataTable popolate dall’applicazione<br />

• Questa tabelle possono essere correlate tra<br />

loro con apposite relazioni<br />

• Si riproduce un DB nella memoria<br />

• Non dipende dal DBMS<br />

• Dichiarazione semplice e anche semplice<br />

istanziazione<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Popolare un DataSet<br />

• Varie possibilità:<br />

• Definire e costruire in modo esplicito gli oggetti DataTable e<br />

aggiungerli al DataSet, definire le relazioni che li legano e popolarli in<br />

un secondo momento leggendo una fonte di dati (anche non<br />

relazionale)<br />

• Usare il metodo Fill dell’oggetto DataAdapter sia per creare sia per<br />

popolare i DataTable del DataSet<br />

• Una libera combinazione dei due metodi precedenti<br />

• Aggiunta di un DataTable a un DataSet è molto semplice:<br />

DataSet ha una collection (Tables) a cui con il metodo Add<br />

posso aggiungere delle DataTable<br />

• Vedi listato CaricaDataSet<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Commenti<br />

• Tre tabelle nel DB – tre DataTable in un DataSet –<br />

tra stringhe per i tre comandi SQL<br />

• Definizione di un DataSet esplicito<br />

• Un unico DataAdapter da usare per le tre tabelle<br />

• La prima stringa SQL e la stringa di connessione si<br />

passano alla creazione del DataAdapter<br />

• Passando al metodo Fill un DataSet dobbiamo<br />

specificare la Table in cui mettere i dati<br />

• La chiave primaria di ogni tabella viene definita<br />

esplicitamente<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Creazione delle relazioni<br />

• Necessario istanziare un oggetto DataRelation<br />

• Nel comando di creazione è necessario specificare:<br />

• Il nome della relazione<br />

• Gli oggetti DataColumn coinvolti<br />

• Un valore booleano che indica se la relazione è attiva o<br />

no<br />

• Vedi listato: CreaRelazioni<br />

• 4 DataColumn e 2 DataRelation<br />

• Per ogni relazione: una coppia di DataColumn di<br />

due DataTable diverse<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


Scrittura del DB<br />

• Due fasi:<br />

• La scrittura influenza solo i dati locali<br />

• La conferma copia nel DB<br />

• Vedi Listato di esempio<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14


SQLCommandBuilder<br />

• Fornisce in modo automatico le istruzioni SQL necessarie per<br />

trasformare le modifiche su un DataTable in aggiornamenti<br />

effettivi su tabelle del DB.<br />

• Per generare le istruzioni di Insert, Update e Delete l’oggetto<br />

SQLCommandBuilder usa la proprietà SelectCommand per<br />

estrarre un set di dati da confrontare con il DataTable che si<br />

intende aggiorenare<br />

• Da questo confronto l’SQLCommandBuilder crea le istruzioni<br />

SQL che saranno eseguire dall’oggetto dataAdapter.<br />

• Vedi : Conferma aggiornamento<br />

• Annullamento molto semplice: basta invocare il metodo<br />

RejectChanges<br />

Inf. Med. - 7. Accesso ai dati -<br />

A.A. 2013/14

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!