WP7 Local Database - Code First Vs Database First

L’uso di SQL Compact all’interno di applicazioni Windows Phone 7 richiede l’approccio Code First, dove siamo noi a definire nel nostro “codice” il modello a oggetti e i relativi attributi che definiscono le opzioni di mapping tra in nostro modello ad oggetti e la relativa struttura dati relazionale (il database).

Ma questa modalità è assai noiosa e “time consuming”, oltre a richiedere una buona conoscenza degli aspetti di gestione dell’integrità del grafo di oggetti che rappresenta i nostri dati.

Infatti, se da una parte è vero che LinqToSQL si occupa di tutti gli aspetti assai complessi legati all’OR/Mapping (alcuni dei quali saranno oggetto di successivi post), è anche vero che lascia al codice contenuto nelle classi del modello l’onere di gestire l’integrità dei dati per quanto attiene alle relazioni tra le entità.

Se, ad esempio, la classe Task contiene un riferimento (EntityRef<Project>) all’istanza della classe Project a cui appartiene, è logico aspettarsi che la classe Project contenga un elenco di riferimenti ad istanze di classe Task (EnitySet<Task>) che sono associate a tale progetto. E compito delle classi Task e Project gestire l’integrità del grafo, dimodoché se ad esempio un Task viene associato ad un diverso progetto, non solo il riferimento al progetto dev’essere ovviamente aggiornato, ma si deve anche togliere il task dall’elenco dei tasks del precedente progetto e dev’essere aggiunto nell’elenco dei task del nuovo progetto.

Quindi, se prima abbiamo un grafo così fatto:

image

Spostando il task 3 dal progetto A al progetto B, dobbiamo aggiornare tutti i dati delle nostre istanze di classe in modo da mantenere l’integrità dei dati e ottenere il nuovo grafo mostrato in figura:

image

Dunque un’operazione apparentemente innocua come:

Task3.Project = ProjectB

Richiede la gestione delle suddette operazioni, il che corrisponde a scrivere per la relazione Task –> Project il seguente codice (all’interno della definizione della classe Task):

private EntityRef<Project> _Project;

[AssociationAttribute(Name="FK_Tasks_Project", ThisKey="Project_FK", OtherKey="Project_PK", IsForeignKey=true)]
public Project Project
{
    get
    {
        return this._Project.Entity;
    }
    set
    {
        Project previousValue = this._Project.Entity;
        if ((previousValue != value) || (this._Project.HasLoadedOrAssignedValue == false))
        {
            this.SendPropertyChanging();
            if ((previousValue != null))
            {
                this._Project.Entity = null;
                previousValue.Tasks.Remove(this);
            }
            this._Project.Entity = value;
            if ((value != null))
            {
                value.Tasks.Add(this);
                this._Project_FK = value.Project_PK;
            }
            else
            {
                this._Project_FK = default(System.Guid);
            }
            this.SendPropertyChanged("Project");
        }
    }
}

Nulla di così terribile, solo che è assai noioso e ripetitivo perché va fatto per tutte le classi e per tutte le relazioni di questo tipo.

Nel prossimo post vedremo come è possibile utilizzare un add-in di Visual Studio che consente l’utilizzo dell’approccio Database First, per la generazione automatica delle classi del modello a oggetti a partire da un database già esistente.

«novembre»
domlunmarmergiovensab
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910