In questo articolo realizzeremo un componente che racchiuda la logica di funzionamento per l'accesso ai dati di un database. Vedremo poi come connettere un simile oggetto ad un GridView, che è un controllo per visualizzare i dati, utilizzando la classe ObjectDataSource
.
Un generico componente che racchiude la logica di funzionamento di una parte di un'applicazione può essere battezzato "oggetto Business" come traduzione dell'inglese "Business Object".
Chi conosce ASP.NET 2.0, potrebbe porsi la seguente domanda: perchè realizzare un componente per accedere ai dati quando lo si può fare utilizzando controlli già pronti?
La risposta a questa domanda va ricercata immaginando situazioni in cui abbiamo bisogno di una logica di funzionamento particolare e, quindi, dobbiamo implementare il nostro componente ad hoc, ma la cosa più importante, che occorre mettere in evidenza, è la possibilità di realizzare un'applicazione a più strati.
Quando si ha a che fare con sistemi di grosse dimensioni, al cui sviluppo partecipano molte figure professionali, è opportuno separare la logica di funzionamento dall'interfaccia utente.
Già in fase di progettazione, ci si muove verso il concepimento di un'architettura multi-strato in cui, una modifica su un componente, posizionato ad un livello, abbia il minor impatto possibile sui componenti posizionati su altri livelli.
Dopo questa breve introduzione, in cui abbiamo giustificato uno studio in questa direzione, realizziamo un esempio di funzionamento dove intervengono un database, un business object, un ObjectdataSource
ed un GridView
.
Il database più immediato che possiamo utilizzare è PUBS.MDF, uno dei database di esempio scaricabili dal sito Microsoft che immaginiamo posizionato in una cartella del nostro disco C, come in figura 1.
Creare il business object
Si tratta di una classe che racchiude una logica di funzionamento. Con il VWD, utilizzando il linguaggio C#, apriamo un New Web Site e chiamiamolo "OggettoBusiness".
Andiamo sul Solution Explorer ed aggiungiamo la cartella App_Code, che è la cartella in cui si inseriscono le classi necessarie al funzionamento dell'applicazione, come illustrato in figura 2.
Aggiungiamo il Web.Config, sempre dal Solution Explorer, con un click destro sul nome del progetto, scegliendo "Add New Item..." e poi "Web Configuration File" sulla finestra che si apre.
Nel Web.Config impostiamo la stringa di connessione a PUBS.MDF come riportato nel listato 1.
Listato 1. Web.Config
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings>
<add name="PUBSConnectionString"
connectionString="Data Source=.SQLEXPRESS;
AttachDbFilename="C:SQL Server 2000 Sample DatabasesPUBS.MDF";
Integrated Security=True;
Connect Timeout=30;
User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="false" />
<authentication mode="Windows" />
</system.web>
</configuration>
Aggiungiamo finalmente una classe alla cartella App_Code cliccando con il pulsante destro del mouse su di essa, nel Solution Explorer, e scegliendo l'Item Class dalla finestra che si apre.
Chiamiamo la classe Authors.cs che ci ricorda il nome della tabella authors del database PUBS.
All'interno della classe implementiamo il metodo getAuthors()
che ha il compito di fare una SELECT
sulla tabella e restituire un DataSet
riempito con i dati di authors.
Listato 2. Implementazione del metodo getAuthors()
using System.Data.SqlClient;
...
public DataSet getAuthors()
{
string PubsConnStr = ConfigurationManager.ConnectionStrings["PUBSConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(PubsConnStr);
string SelectSQL = "SELECT au_id, au_fname, au_lname FROM authors";
SqlDataAdapter adapter = new SqlDataAdapter(SelectSQL, conn);
DataSet ds = new DataSet();
adapter.Fill(ds, "authors");
return ds;
}
Questo metodo prende la stringa di connessione dal Web.Config e costruisce la connessione conn
. Definisce quindi il comando SQL da utilizzare per leggere i dati, per mezzo del quale con la Connection conn
costruisce il DataAdapter adapter
. Definisce poi un DataSet
che riempie e restituisce con i dati letti.
Inoltre, affinchè getAuthors
funzioni, dobbiamo dire alla classe Authors
di usare System.Data.SqlClient
che contiene la definizione di alcune classi usate.
Per utilizzare la classe che abbiamo scritto e per fare in modo che il VWD la riconosca e la metta a disposizione, dobbiamo controllare che non ci siano errori e compilarla. Quindi clicchiamo con il pulsante destro del mouse sul nome del progetto, nel Solution Explorer, poi su Build Web Site, come riportato in figura.
Collegare l'oggetto business con lo strato di presentazione
Aggiungiamo adesso un GridView
in Design view della pagina Default.aspx. In Choose Data Source clicchiamo su New Data Source. Selezioniamo quindi Object, nella finestra che ci appare, e lasciamo il nome di default, ObjectDataSource1
. Andiamo avanti cliccando su OK. Nella finestra successiva scegliamo il business object che abbiamo realizzato, Authors, ed andiamo avanti con Next.
Nella finestra successiva, selezioniamo la linguetta SELECT e scegliamo il metodo da utilizzare.
Clicchiamo quindi su Finish ed abbiamo così configurato il nostro ObjectDataSource
.
Possiamo adesso testare la nostra applicazione premendo F5.
Aggiornare il database
Con il GridView
, l'ObjecDataSource
ed il business object possiamo anche operare l'aggiornamento del database. Implementiamo il metodo updateAuthors()
nella classe Authors aggiungendo codice nel file Authors.cs .
Listato 3. Implementazione del metodo updateAuthors()
public void updateAuthors(string au_id, string au_fname, string au_lname)
{
string PubsConnStr = ConfigurationManager.ConnectionStrings["PUBSConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(PubsConnStr);
string SelectSQL = "SELECT au_id, au_fname, au_lname FROM authors WHERE au_id=@au_id";
SqlDataAdapter adapter = new SqlDataAdapter(SelectSQL, conn);
DataSet ds = new DataSet();
adapter.SelectCommand.Parameters.Add("@au_id", SqlDbType.NVarChar, 11).Value = au_id;
adapter.Fill(ds, "authors");
ds.Tables[0].Rows[0][1] = au_fname;
ds.Tables[0].Rows[0][2] = au_lname;
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
adapter.Update(ds, "authors");
}
Il metodo updateAuthors()
prende in input tre parametri, il primo au_id
serve a trovare il record da aggiornare, gli altri due sono i valori con cui aggiornare i campi.
Dobbiamo poi configurare l'ObjectDataSource
per l'Update. Quando arriviamo alla finestra Define Data Methods, clicchiamo sulla linguetta UPDATE e scegliamo il metodo.
Sul GridView
spuntiamo Enable Editing, inoltre, volendo essere precisi, dobbiamo fare in modo che au_id
sia un campo di sola lettura, cioè non aggiornabile. Per fare questo, sul GridView Tasks clicchiamo su Edit Columns... per ottenere la schermata riportata in figura 8. Qui togliamo Auto-generate fields ed aggiungiamo i nostri BoundField.
Sulle Properties del GridView specifichiamo il DataKeyNames che nel nostro caso è au_id
e, nelle Properties del BoundField con DataField au_id
, impostiamo ReadOnly a true.
A questo punto possiamo testare l'update. Premiamo F5 e clicchiamo sul comando edit di una riga.
Proviamo a fare una modifica ed a cliccare su Update, il record verrà aggiornato.
Inserimento e cancellazione
Allo stesso modo visto per la modifica, possiamo aggiungere i metodi per l'inserimento e la cancellazione di record. Per completezza, nei listati 4 e 5, riportiamo degli esempi di implementazione di questi metodi utilizzando il DataAdapter.
Listato 4. Esempio di implementazione del metodo insertAuthors()
public void insertAuthors(string au_id, string au_fname, string au_lname, string phone, string address, string city, string state, string zip, Boolean contract)
{
string PubsConnStr = ConfigurationManager.ConnectionStrings["PUBSConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(PubsConnStr);
string SelectSQL = "SELECT * FROM authors";
SqlDataAdapter adapter = new SqlDataAdapter(SelectSQL, conn);
DataSet ds = new DataSet();
adapter.Fill(ds, "authors");
DataRow nuovaRiga = ds.Tables["authors"].NewRow();
nuovaRiga["au_id"] = au_id;
nuovaRiga["au_fname"] = au_fname;
nuovaRiga["au_lname"] = au_lname;
nuovaRiga["phone"] = phone;
nuovaRiga["address"] = address;
nuovaRiga["city"] = city;
nuovaRiga["state"] = state;
nuovaRiga["zip"] = zip;
nuovaRiga["contract"] = contract;
ds.Tables["authors"].Rows.Add(nuovaRiga);
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
adapter.Update(ds, "authors");
}
Listato 5. Esempio di implementazione del metodo deleteAuthors()
public void deleteAuthors(string au_id)
{
string PubsConnStr = ConfigurationManager.ConnectionStrings["PUBSConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(PubsConnStr);
string SelectSQL = "SELECT * FROM authors WHERE au_id=@au_id";
SqlDataAdapter adapter = new SqlDataAdapter(SelectSQL, conn);
DataSet ds = new DataSet();
adapter.SelectCommand.Parameters.Add("@au_id", SqlDbType.NVarChar, 11).Value = au_id;
adapter.Fill(ds, "authors");
ds.Tables[0].Rows[0].Delete();
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
adapter.Update(ds, "authors");
}
Il codice sorgente dell'esempio sviluppato in questo articolo può essere scaricato da qui.