Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

[MCAD.19] Salvare e leggere i nostri compleanni in files XML con ADO.NET

Ok, dopo il preambolo di prima, dove abbiamo illustrato in po' di semplice teoria che sta dietro ad ADO.NET, passiamo finalmente a fare qualcosa di concreto nella nostra applicazione Age.

In pratica, vogliamo dare all'utente la possibilità di salvare la lista dei compleanni e successivamente di ricaricarla . In condizioni normali dovremmo utilizzare un qualsiasi database. Questa volta vorrei adottare un approccio diverso e più interessante: invece di usare un database di Access o di SQL Server, salveremo le informazioni in files XML generati direttamente senza grossi problemi da ADO.NET.

Come ho detto nel post precedente, vogliamo utilizzare la modalità disconnessa di ADO.NET.

Quindi, andremo a creare in memoria una complessa struttura dati (DataSet). Questa struttura dati può contenere una o più tabelle (DataTable): a noi ne serve una soltanto, ovvero la tabella che conterrà l'elenco dei compleanni inseriti e correntemente visualizzati nella ListBox della Windows Form (WF). Ogni DataTable contiene uno o più oggetti DataRow, che non sono nient'altro che i records della nostra tabella.
La struttura della tabella è formata da tanti oggetti DataColumn, che sono i campi (fields) della nostra tabella. Quali campi servono nel nostro caso? Beh, semplice, basta dare un'occhiata alla classe Age per capirlo. Avremo un campo Name (stringa) e un campo BirthDate (DateTime). Ne aggiungeremo un altro via codice per divertirci un po'.

Come si traduce tutto questo in .NET?
Beh, ormai la sintassi di C# ci è familiare, per cui...ecco un po' di codice.

private DataTable getSaveTable(bool WithData)
{
    DataRow dr;
    DataColumn dtField;
    
// creo l'istanza dtBirthdays che ritornerò al chiamante
    
DataTable dtBirthdays = new DataTable();
    dtBirthdays.CaseSensitive = 
false;
    dtBirthdays.TableName = "ListBirthdays";

    
// creo le DataColumn che mi servono
    // nome
    
dtField = new DataColumn("Name", Type.GetType("System.String"), string.Empty);
    dtBirthdays.Columns.Add(dtField);
    
// data di nascita
    
dtField = new DataColumn("BirthDate", Type.GetType("System.DateTime"), string.Empty);
    dtBirthdays.Columns.Add(dtField);
    
// oggi
    
dtField = new DataColumn("Today", Type.GetType("System.DateTime"), string.Empty);
    dtField.DefaultValue = DateTime.Now;
    dtBirthdays.Columns.Add(dtField);

    
// riempio il DataTable con i dati, solo se richiesto
    
if (WithData == true)
    {
        
// con un foreach ciclo gli elementi contenuti nella ListBox
        
foreach (object item in this.lstResults.Items)
        {
            dr = dtBirthdays.NewRow();
            Age ageTemp = (Age) item;
            dr["Name"] = ageTemp.Name;
            dr["BirthDate"] = ageTemp.BirthDate;
            dtBirthdays.Rows.Add(dr);
        }
    }

    
// libero la memoria degli oggetti che implementano l'interfaccia IDispose
    
dtField.Dispose();
    
// ritorno la tabella
    
return(dtBirthdays);
}

Abbiamo creato una function getSaveTable. Ritorna un'istanza di DataTable: se il parametro WithData vale true, allora la DataTable contiene anche i dati, altrimenti soltanto la struttura. Cosa vuol dire "contiene anche i dati"? In breve, la property Rows di dtBirthdays conterrà tanti oggetti DataRow quanti sono gli Items della ListBox (pensiamo ad ogni DataRow come ad un record di una tabella).

Esaminiamo riga per riga la function. Creo un'istanza di DataTable chiamata dtBirthdays, specifico che il contenuto è case-insensitive e gli do un nome, cioè "ListBirthdays". Attenzione: la struttura della tabella fino a questo momento è vuota! Dato che non abbiamo un database reale, .NET non conosce i campi, perciò glielo dobbiamo specificare noi. Come? La risposta è nelle righe successive.

Usando dtField, creo tanti oggetti DataColumn. Sfruttando il costruttore della classe, li creo indicando, nell'ordine: nome del campo, tipo dati e una expression (nel nostro caso, sempre string.Empty). Una volta creato ciascun dtField, lo aggiungo alla collection Columns della nostra DataTable dtBirthdays. In questo modo, creo una piccola tabella in memoria con tre campi: Name, BirthDate e Today. Per creare quest'ultimo ho utilizzato la property DefaultValue per impostare un valore predefinito per i nuovi "records" (chiamiamoli così, ma ricordiamoci che in realtà saranno DataRow). Ogni istanza di DataColumn ha moltissime proprietà, esploratele e vedrete! Dedicherò un post al riguardo, perchè si possono scoprire diverse cose interessanti. Ok, a questo punto abbiamo in memoria pronta per accogliere tutti i dati che ci servono: come la popoliamo? Vediamolo subito...

Innanzitutto, ricordiamoci del parametro WithData: se il suo valore è false, possiamo uscire dalla function, perchè abbiamo richiesto la creazione della DataTable vuota, senza dati. Se vale true, proseguiamo con il codice. Con l'implementazione del ciclo foreach, ciclo tutti gli Items della ListBox. Riporto qui sotto il codice per maggiore chiarezza:

foreach (object item in this.lstResults.Items)
{
    dr = dtBirthdays.NewRow();
    Age ageTemp = (Age) item;
    dr["Name"] = ageTemp.Name;
    dr["BirthDate"] = ageTemp.BirthDate;
    dtBirthdays.Rows.Add(dr);
}

Ricordiamoci quello che abbiamo fatto per aggiungere un Item alla ListBox: la nostra classe Age fa l'overloading del metodo ToString(): questo vuol dire che ogni Item è anche un'istanza di Age. Questo è il motivo per cui il casting (Age) item non dà alcun problema. Con una sola istruzione, possiamo accedere alle property Name e BirthDate dell'Item corrispondente. Vediamo come popolare adesso la nostra DataTable.

dr è una nuova istanza di DataRow (che possiamo assimilare come un nuovo record) che viene restituita dalla chiamata del metodo NewRow() della nostra DataTable. La cosa interessante è che .NET in questo caso ci aiuta: dr è una vera e propria tabella, che contiene le DataColumn che abbiamo creato prima: ogni DataColumn ha un suo nome, perciò possiamo tranquillamente scrivere dr["Name"] = "Nome della persona". Notate l'uso delle parentesi quadre: la sintassi ci dice che .NET sta manipolando array in memoria. Una volta valorizzati i due campi (accedendo tramite ageTemp), aggiungo la DataRow a dtBirthdays. Tutto in memoria. Una volta terminato il ciclo foreach, chiamo la Dispose() sugli oggetti temporanei che ho utilizzato e ritorno al chiamante la DataTable che ho creato.

Questa function è la struttura portante delle nuove features che aggiungeremo alla nostra applicazione. Provate a ritornare all'inizio di questo post: vi avevo parlato di una complessa struttura dati chiamata DataSet. Non l'abbiamo ancora utilizzata, non vi pare? Questo sarà tema dei prossimi post, nei quali vedremo come creare un DataSet, come aggiungere la DataTable che abbiamo visto adesso e cosa possiamo fare con il DataSet, che, come ho detto prima, è il vero fulcro del discorso.

Alla prossima!

powered by IMHO 1.2

Print | posted on martedì 26 luglio 2005 20:51 | Filed Under [ MCAD ]

Feedback

Gravatar

# re: [MCAD.19] Salvare e leggere i nostri compleanni in files XML con ADO.NET

Le classi a cui mi riferisco sono le classi per la gestione dei dati disconnessi.
26/07/2005 23:32 | Roberto Valenti
Gravatar

# [MCAD.20] Espandiamo il MainMenu per far posto alle nuove features di oggi

27/07/2005 16:02 | Technology Experience
Gravatar

# re: [MCAD.19] Salvare e leggere i nostri compleanni in files XML con ADO.NET

In italiano le parole straniere sono invarianti. Non si dice "files" ma file, così come non dici "guardo molti films" e "compro due mice"
02/04/2007 21:39 | Mark
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET