LINQ to SQL: Disegnare gli oggetti in C#, prima di creare il DB

Non sto dicendo che si dovrebbe eliminare la pianificazione del database dai documenti di progettazione di un nuovo applicativo. Niente affatto. La progettazione del database è una parte importante della processo di sviluppo e non dovrebbe mai essere trascurato, se necessario. Allo stesso tempo, a volte è più facile iniziare il processo di progettazione in un altro modo – la meno comune.

Dalla mia esperienza, nella progettazione di un database fin dall’inizio si dà una struttura piuttosto rigida. Dopo aver definito le tabelle e creato alcune stored procedure, gli sviluppatori iniziano a lavorare sulle loro applicazioni cercando di adattare l’applicazione alle condizioni esistenti del DB e spesso essi devono raggiungere compromessi perché una piccola modifica a una tabella di DB può rovinare tutta una catena di relazioni tra tabelle.

La tecnica di cui vorrei parlare è chiamata ORM, o object-relational mapping . Al suo centro è l’idea che specifiche tipologie di informazioni o proprietà possono essere facilmente convertite in valori che possono essere memorizzati in un database (nella maggior parte dei casi, basato su SQL) – dunque, semplici (scalari), tipi di valore.

Per fare un esempio, se si dispone di un oggetto di tipo di veicolo che è un insieme di proprietà (ad esempio, peso, velocità, colore), non è possibile salvarlo direttamente in un database SQL come un oggetto – è necessario convertire ogni singola proprietà in uno tipo semplice e memorizzarli nel contesto di una entità (riga) che rappresenterà l’oggetto del veicolo.

Facciamo un esempio di come questo viene fatto in C#, voglio creare una classe molto semplice che possa rappresentare un modello di dati e utilizza LINQ to SQL per creare una base di dati intorno ad esso. E sebbene LINQ to SQL viene lentamente sostituito da Entity Framework, per questo breve tutorial sarà sufficiente per acquisire familiarità con alcuni dei concetti di base.

Ecco la classe base che rappresenta un veicolo in cui VIN è l’identificativo univoco:

public class Veicolo
{
    public string VIN { get; internal set; }
    public string Tipo { get; set; }
    public string Nome { get; set; }
    public DateTime DataFabbricazione { get; set; }
} 

Prima di proseguire, assicuratevi di avere i corretti riferimenti:

using System.Data.Linq;
using System.Data.Linq.Mapping;

Ecco come viene trasformata la classe per il database, che è quella che effettivamente useremo nel codice:

[Table(Name="Veicoli")]
public class Veicolo
{
    [Column(IsPrimaryKey=true,CanBeNull=false,IsDbGenerated=false)]
    public string VIN { get; internal set; }
    [Column]
    public string Tipo { get; set; }
    [Column]
    public string Nome { get; set; }
    [Column]
    public DateTime DataFabbricazione { get; set; }
}

Gli attributi definiscono la struttura della tabella. Per esempio, definisco il nome della tabella quando dichiaro la classe, questo non è obbligatorio, ma è consigliabile per avere delle regole comuni di progettazione. Lo stesso concetto vale per le colonne, il cui nome viene preso direttamente dal nome delle proprietà della classe, quindi non devo impostare in modo esplicito il loro nome.

VIN sarà la chiave primaria – è unico, quindi è perfetto per una chiave primaria. Inoltre, non viene generato dal DB e non può essere nullo. Se usassi un semplice campo ID per la chiave primaria, allora non ci sarebbe assolutamente nessun problema nel fissare i valori perchè verrebbero generati direttamente dal DB con un meccanismo di auto-incremento.

Così ora c’è una struttura. Come diventa un DB? Prima di tutto, la maggior parte degli oggetti di LINQ to SQL girano intorno a DataContext che è la connessione dati . E ‘l’anello di congiunzione tra l’applicazione e la database. Dato che ho già una struttura di base, posso creare un’istanza di DataContext che si connette al mio database (con una stringa di connessione esistente):

DataContext dc = new DataContext("Data Source=(local);Integrated Security=SSPI;Initial Catalog=VEICOLI_DB;");

Ora che c’è una connessione, è possibile passare una tabella all’istanza di DataContext:

dc.GetTable();

Questa istruzione ritornerà come risultato il set di tabelle che sono basate sull’entità veicolo. Siccome non ci sono tabelle definite sull’entità passata, una tabella verrà creata secondo le regole definite dagli attributi. Alla fine io devo solo fare questo per creare il database:

dc.CreateDatabase();

Anche se il database definito nella stringa di connessione non esiste, sarà creato. Ora, diamo uno sguardo al server per vedere se il database effettivamente c’è:

Sql Server Veicoli

Come si può vedere, l’utilizzo di un ORM consente di risparmiare tempo (e un pò di righe di codice), quando si tratta di creare un DB in base alle esigenze specifiche di un applicazione. Naturalmente il maggior vantaggio si otterrà con progetti complessi, questa semplificazione porta alcune volte gli sviluppatori a commettere degli errori come la non ottimizzazione delle query.

Continua a seguirmi perchè prossimamente approfondirò l’argomento, e tu hai mai usato LINQ to SQL in C#?