2 giu 2011

Un DAL apolide (prima parte)

Nel corso dei progetti CDS (per aipa) e LabDB (per trw) abbiamo cercato di creare uno strato di software che permettesse, fatti salvi alcuni punti vincolanti che andremo a elencare nel seguito, di delegare la persistenza degli oggetti su un database (oracle, sql server o mysql) - senza dover scrivere esplicitamente le query per ogni oggetto.

Funzionalità 
Nel dettaglio, questo layer dovrebbe, senza altre informazioni che il tipo coinvolto (ovvero la definizione di classe) e la stringa di connessione, essere in grado di generare:

  1. select di tutti i record (select * from tabella)
  2. select di un record in base alla chiave primaria (select * from tabella where primarykey=x) 
  3. update di un record (update tabella set campo1=valore1, campo2=valore2, .... where primarykey=x) 
  4. delete di un record (delete from tabella where primarykey=x) 


Vincoli e Limitazioni
I vincoli che vanno rispettati sono:

  • gli oggetti del modello devono essere definiti con proprietà pubbliche ed attributi privati. Le proprietà pubbliche sono usate dal DAL per riempire i campi della tabella corrispondente alla classe. 
  • il modello ad oggetti deve essere definito in modo per cui ogni elemento sia contraddistinto da una ed una sola chiave primaria generata automaticamente (per esempio, un autoincrementale del db, oppure un GUID generato da un'authority) 
  • se nel modello c'è un riferimento tra la classe C1 e la classe C2 (relazione 1:n), allora sul database occorre che venga registrata la chiave della riga referenziata (della tabella C2) in un campo del record corrispondente all'oggetto che referenzia (sulla tabella C1) - esempio: la classe veicolo ha una proprietà ptarga, puntatore alla classe targa; sul database il campo ptarga della tabella veicolo conterrà una chiave esterna che referenzia la chiave primaria (id autoincrementale o GUID) della tabella targa. 
  • non gestiamo le relazioni n:m, perché occorrerebbe gestire tabelle di relazione con la reflection, cosa che introduce una complessità non giustificabile per i vantaggi offerti. 
  • di norma vengono salvate sul database tutte le proprietà degli oggetti; se si desidera creare una proprietà di comodo, cui non corrisponda un campo della tabella, si preponga alla definizione della proprietà l'attributo [Support]


Attenzione a... 
Un ulteriore problematica da tenere in considerazione è la corretta apertura e chiusura delle connessioni al database; come regola generale diciamo che:

Ogni funzione pubblica esposta dal DAL deve creare una connessione (possibilmente facendosela fornire dal connection pool), quindi aprire un blocco try all'interno del quale incorporare la logica di accesso ai dati, e terminare con un finally all'interno del quale la connessione va chiusa.

Tutte le chiamate private (interne al DAL stesso) NON devono più aprire la connessione, ma, alternativamente:
  • farsela passare come parametro (se il DAL prevede connessioni a più database) 
  • usare una proprietà privata che contiene la connessione aperta (se il DAL accede sempre ad un unico db e se risponde ad un unico client) 

in pratica la seconda opzione è percorribile solo se si sviluppa una soluzione rich-client (Win32, WinForm...) - mentre per le soluzioni distribuite (Web-services, Silverlight, ASP.NET, ecc..) occorre usare la prima tecnica.

Nella seconda parte dell'articolo vedremo in dettaglio le caratteristiche di un DAL inserito in un'architettura software distribuita.

Nessun commento:

Posta un commento