SISTEMI INFORMATIVI E TELEMEDICINA 7. Accesso ai dati Prof. Mauro Giacomini
Sommario Proprietà e metodi dei seguenti oggetti DataReader DataAdapter DataTable DataSet t
DataReader: caratteristiche Contiene solo una struttura dati alla volta (il risultato di un unicaunica query) i valori di un solo record alla volta Solo lettura sequenziale no ordinamento no accesso casuale no cambiamento dei valori nei DB Lettura solo connessa Ottimizzazione elevata Tre tipi per i 3 diversi data provider
SqlDataReader: Confronti Protocollo di comunicazione col server proprio dei client di SqlServer Tabular Data Stream (TDS) Assenza di provider intermedi Metodi di accesso ai dati che restituiscono i datatype nativi di SQL Server: minimizzazione delle perdite di precisione
Creazione del DataReader Importazione del namespace Dichiarazione Istanziazione specifica con il metodo New Item: proprietà che restituisce il valore di una colonna del record dei dati estratti Colonna specificata con il nome (nome del campo della tabella o alias pubblicato nella query) o la posizione ordinale nel record (si parte da 0) FieldCount: proprietà che restituisce il numero dei campi del record corrente.
DataReader: metodi (1) Ottiene i dati con il metodo ExecuteReader dell oggetto Command DataReader non contiene i dati estratti, ne consente solo la lettura con il metodo Read Si deve sempre invocare il metodo Read all inizio per generare il puntatore ai dati Se la lettura ha dato esito positivo il valore di Read è true Si legge in un loop da cui si esce quando Read restituisce false Close: metodo di chiusura della connessione e dell oggetto DataReader stesso Chiusura automatica gestita dalla proprietà CommandBehaviour GetName: restituisce una stringa contenente il nome della colonna (indicata con la posizione ordinale), serve per le intestazioni delle tabelle GetOrdinal: restituisce un numero indicante la posizione della colonna all interno del record (indicata con il nome del campo)
Esempio: commenti Vedi Routine LeggiDataReader Estrazione dei dati da visualizzare Generazione della stringa SQL Uso di procedura esterna Lettura in un ciclo While Identificazione del primo record Scrittura dell intestazione dei dati stessi con un ciclo For Scrittura del contenuto dei campi stessi con un altro ciclo for più esterno, usando la proprietà item
Uso del DataReader: Esempio Caricamento di oggetti visuali come ListBox e ComboBox Scopo: leggere tutti i record della tabella Prodotti e metterne in nomi nel controllo lstprodotti (vedi routine CaricaListBox) con il metodo Add della collection Items della lista stessa Questa Routine deve essere chiamata dall evento load della form Gli oggetti di tipo lista possono contenere nella lista degli items oggetti più complessi del solo nome La struttura degli item può essere definita con apposite classi
Definizione delle classi Selezionare AddClass dal menu progetto, specificandone il nome Vedi listato clsprodotto Una proprietà per ogni informazione di dettaglio che si vuole gestire Classe Generale per un oggetto numerico con descrizione alfanumerica, con due proprietà: IdOggetto: codice numerico NomeOggetto: descrizione dell oggetto Usata per caricare le ComboBox dei fornitori e delle categorie
Caricamento della ListBox Vedi il listato di CaricaListBoxClassLong SQL più articolata per valorizzare la classe clsprodotto Per ogni record è creato un nuovo oggetto istanziando la classe, le cui proprietà sono valorizzate leggendo la proprietà Item dell oggetto DataReader Si aggiunge il prodotto alla lista con il metodo Add della collezione Items della lista Quello che si vede nella lista è determinato dalla funzione ToString della classe clsprodotto invocata all atto della valorizzazione della proprietà NomeProdotto, la sua ridefinizione nella classe fa sì che la proprietà NomeProdotto sovrascriva tutte le altre in fase di visualizzazione
Caricamento delle ComboBox Si usano istanze della classe clsoggettonum Vedi il listato CaricaFornitori Per ogni record è creato un oggetto della classe le cui proprietà sono valorizzate con gli item del record stesso Si aggiunge l oggetto agli item della ComboBox Anche qui una proprietà p sovrascrive le altre in fase di visualizzazione Esercizio: scrivere la CaricaCategorie Tutte queste procedure devono essere eseguite durante il load della form
Visualizzazione (1) Scopo: popolare gli oggetti con i dettagli dell Item selezionato Nelle TextBox basta l assegnazione diretta Nelle ComboBox va individuato il valore al loro interno (vedi listato: CercaItemInCombo). Alla routine si passa l oggetto in cui cercare (byref modificabile) e lid l id da cercare (byval immodificable)
Visualizzazione (2) Scopo caricare i dettagli nella form Vedi listato CaricaFormCollection Generazione dell oggetto di tipo clsprodotto con l istruzione CType che converte un oggetto che appartiene alla collezione degli item della lista in un oggetto della classe clsprodotto. Le proprietà di questo oggetto popolano i record o direttamente o con la subroutine vista prima Questa visualizzazione deve essere innescata dall evento SelectedIndexChanged della lista dei prodotti
Sequenza di esecuzione Alla load sono chiamate le routine di caricamento di fornitori, categorie e alla fine dei prodotti Quando sono caricati tutti i prodotti la selezione automatica ti del primo prodotto della lista fa scattare l evento SelectedIndexChanged così anche gli altri controlli sono caricati correttamente
Modifiche: Aggiornamento Creare un nuovo oggetto di tipo clsprodotto Popolare le proprietà p con i nuovi valori digitati negli oggetti Eseguire una query di update Vedi listato AggiornaPropProdotto per la popolazione delle proprietà dell oggetto clsprodotto Di nuovo si usa CType Vedi listato AggiornaRecProdotto per la scrittura della tabella Prodotti Scrive i parametri della query di update dalle proprietà p dell oggetto clsprodotto Chiama la procedura EseguiWriteParametrica L aggiornamento è eseguito alla pressione del tasto aggiorna. Vedi listato: btnaggiorna_click Dopo l aggiornamento si deve ricaricare la lista dei prodotti Selezionare di nuovo il prodotto modificato per vedere se le modifiche sono state registrate
DataTable DataColumn (1) Contenitore di memoria strutturato in modo del tutto simile alla tabella di un DB. Non dipende dal DBMS interfacciato. Creazione esplicita con il comando new Proprietà TableName: nome univoco Definizione dei campi che compongono il record: oggetto DataColumn Columns: Proprietà di tipo collection che contiene i campi fra i quali coloro che costituiscono la chiave primaria Creazione esplicita con il comando new Proprietà ColumnName: nome univoco in ogni tabella Proprietà DataType: ottenuta con il metodo GetType
DataColumn (2) Possibilità di definire dei vincoli con le proprietà booleane Unique AllowDBNull La tabella ha una collezione di colonne Columns a cui la colonna definita e completata può essere aggiunta con il metodo Add Possibile definire una lunghezza massima MaxLength
DataRow Definizione ed assegnazione ad una DataTable per indicarne la struttura Accoglie i record da gestire, con la valorizzazione di tutti i campi Quando tutti i campi obbligatori hanno valore si inserisce la riga nella collezione Rows della tabella con il comando Add
DataAdapter Fornisce più funzionalità rispetto a DataReader Indicato per estrarre dati da manipolare Dipende dal particolare DBMS Creazione con New Necessita di: Comando Valido Connessione attiva È possibile sia associare a un DataAdapter il comando e la connessione in due modi Associando dei comandi e delle connessioni precedentemente definite Passando all atto della istanziazione due parametri: la stringa di SQL e la stringa di connessione, in questo secondo caso la connessione sarà completamente gestita dal DataAdapter
DataAdapter e DataTable Il metodo Fill riempe un DataTable di cui non si deve neppure definire la struttura Tale tabella rimane in memoria, svincolata dalla conessione e possiamo scorrerla a piacimento evitando le limitazioni che avevamo con il DataReader. Vedi listato: CaricaListBoxDataTable Si scorrono tutte le Row del DataTable e per ogni row si genera un oggetto del tipo clsprodotto Anche le ComboBox possono essere riempite con DataAdapter e DataTable, vedi listato: CaricaFornitoriDataTable
DataSet DataSet: contenitore di oggetti di tipo DataTable popolate dall applicazione li i Questa tabelle possono essere correlate tra loro con apposite relazioni Si riproduce un DB nella memoria Non dipende dal DBMS Dichiarazione semplice e anche semplice istanziazione
Popolare un DataSet Varie possibilità: Definire e costruire in modo esplicito gli oggetti DataTable e aggiungerli al DataSet, definire le relazioni che li legano e popolarli in un secondo momento leggendo una fonte di dati (anche non relazionale) Usare il metodo Fill dell oggetto DataAdapter sia per creare sia per popolare i DataTable del DataSet Una libera combinazione i dei due metodi precedenti Aggiunta di un DataTable a un DataSet è molto semplice: DataSet ha una collection (Tables) a cui con il metodo Add posso aggiungere delle DataTable Vedi listato CaricaDataSet
Commenti Tre tabelle nel DB tre DataTable in un DataSet tra stringhe per i tre comandi SQL Definizione di un DataSet esplicito Un unico DataAdapter da usare per le tre tabelle La prima stringa SQL e la stringa di connessione si passano alla creazione del DataAdapter Passando al metodo Fill un DataSet dobbiamo specificare la Table in cui mettere i dati La chiave primaria di ogni tabella viene definita esplicitamente
Creazione delle relazioni Necessario istanziare un oggetto DataRelation Nel comando di creazione è necessario specificare: Il nome della relazione Gli oggetti DataColumn coinvolti Un valore booleano che indica se la relazione è attiva o no Vedi listato: CreaRelazioni 4 DataColumn e 2 DataRelation Per ogni relazione: una coppia di DataColumn di due DataTable diverse
Scrittura del DB Due fasi: La scrittura influenza solo i dati locali La conferma copia nel DB Vedi Listato: AggiornaProdottoDataSet e InserisciProdottoDataSet ip t t
SQLCommandBuilder Fornisce in modo automatico le istruzioni SQL necessarie per trasformare le modifiche su un DataTable in aggiornamenti effettivi su tabelle del DB. Per generare le istruzioni di Insert, Update e Delete l oggetto SQLCommandBuilder usa la proprietà SelectCommand per estrarre un set di dati da confrontare con il DataTable che si intende aggiorenare Da questo confronto l SQLCommandBuilder crea le istruzioni i i SQL che saranno eseguire dall oggetto dataadapter. Vedi : Conferma aggiornamento Annullamento molto semplice: basta invocare il metodo RejectChanges