L'entity Framework e i vincoli FOREIGN KEY

di Andrea Zani, in .NET,

L'entity framework rende felice. Ti fa vedere il mondo dei database sotto un'altra ottica. Le complicazioni create dai soliti esperti di struttura dei database fanno ora sorridere, anzi, li si incita a complicare maggiormente la struttura delle tabella per normalizzazioni fino al quinto livello.

- Il terzo livello basta!
- No, andiamo fino al quinti livello di normalizzazione! - possono ora affermare i dev sorseggiando un caffè alle loro spalle.

A parte queste ciance, una delle attenzioni che si devono avere quando si usa l'Entity Framework è quando si cancellano delle entity dal database quando sono in gioco Foreign key e amenità simili. Inoltre, la cancellazione di una entità non elimina - giustamente - di suo eventuali proprietà collegate uno-a-uno con un'altra tabella (sempre che sul db non ci siano regole varie, ma in questo caso di deve prestare attenzione, perché la cache interna dell'Entity Framework la vedrà ancora presente). Buona regola, nel caso di voler cancellare tutti i record coinvolti in una entità, scrivere:

using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2())
{
    var padre = context.Canc_Padre.Include("Canc_Figlia").First();
    var figlia = padre.Canc_Figlia;
    context.DeleteObject(figlia);
    context.DeleteObject(padre);
    context.SaveChanges();
}

In questo caso le tabelle di chiamano Canc_Padre e Canc_Figlia. L'ordine di cancellazione dev'essere anche quello mostrato (prima la tabella figlia e poi la padre), perché la cancellazione dell'entità padre farebbe perdere il collegamento con il record da cancellare con la necessità di una nuova query di select di ricerca.

Ma nel caso delle relazioni molti-a-molti? Prendiamo d'esempio un classico schema con tre tabelle:

  1. authors
  2. books
  3. authorsbooks

Le prime due sono le classiche tabelle che conterranno i dati, la terza quella che collega i dati delle due.

Scrivendo questo codice:

using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2())
{
    var coll = (from au in context.authors
               where au.name=="..."
               select au).First();
    context.DeleteObject(coll);
    context.SaveChanges();
}

Otterremo il classico errore:

L'istruzione DELETE è in conflitto con il vincolo REFERENCE "FK_authors_books_authors". Il conflitto si è verificato nella tabella "dbo.authorsbooks", column 'id_author' del database "pubs".

Per evitare questo problema, cioè cancellare il record dalla tabella authors e ogni suo riferimento dalla tabella authorsbooks, dovremo invece scrivere:

using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2())
{
    var coll = (from au in context.authors.Include("books")
               where au.name=="..."
               select au).First();
    context.DeleteObject(coll);
    context.SaveChanges();
}

Se volessimo cancellare anche il record in book, dovremo fare come sopra: recuperata l'entity usare il DeleteObject.

PS: ieri sera ho dovuto aspettare venti minuti il pullman per tornare a casa.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese