Entity Framework - Ciclo di vita

Tutta la vita

La durata di un contesto inizia quando l'istanza viene creata e termina quando l'istanza viene eliminata o sottoposta a garbage collection.

  • La durata del contesto è una decisione cruciale da prendere quando usiamo ORM.

  • Il contesto si comporta come una cache di entità, quindi significa che contiene riferimenti a tutte le entità caricate che possono crescere molto velocemente nel consumo di memoria e può anche causare perdite di memoria.

  • Nel diagramma sottostante, puoi vedere il livello superiore del flusso di lavoro dei dati dall'applicazione al database tramite il contesto e viceversa.

Ciclo di vita dell'entità

Il ciclo di vita dell'entità descrive il processo in cui un'entità viene creata, aggiunta, modificata, eliminata, ecc. Le entità hanno molti stati durante la sua vita. Prima di esaminare come recuperare lo stato dell'entità, diamo un'occhiata a cos'è lo stato dell'entità. Lo stato è un enum di tipoSystem.Data.EntityState che dichiara i seguenti valori -

  • Added: L'entità è contrassegnata come aggiunta.

  • Deleted: L'entità è contrassegnata come eliminata.

  • Modified: L'entità è stata modificata.

  • Unchanged: L'entità non è stata modificata.

  • Detached: L'entità non viene tracciata.

Cambiamenti di stato nel ciclo di vita dell'entità

A volte lo stato delle entità viene impostato automaticamente dal contesto, ma può anche essere modificato manualmente dallo sviluppatore. Anche se tutte le combinazioni di passaggi da uno stato all'altro sono possibili, ma alcune di esse sono prive di significato. Per esempio,Added entità al Deleted stato o viceversa.

Parliamo di stati diversi.

Stato invariato

  • Quando un'entità è invariata, è vincolata al contesto ma non è stata modificata.

  • Per impostazione predefinita, un'entità recuperata dal database si trova in questo stato.

  • Quando un'entità è collegata al contesto (con il metodo Attach), allo stesso modo si trova nello stato Unchanged.

  • Il contesto non può tenere traccia delle modifiche agli oggetti a cui non fa riferimento, quindi quando sono collegati presuppone che siano invariati.

Stato distaccato

  • Staccato è lo stato predefinito di un'entità appena creata perché il contesto non può tenere traccia della creazione di alcun oggetto nel codice.

  • Questo è vero anche se installi l'entità all'interno di un blocco using del contesto.

  • Staccato è anche lo stato delle entità recuperate dal database quando il rilevamento è disabilitato.

  • Quando un'entità viene scollegata, non è vincolata al contesto, quindi il suo stato non viene tracciato.

  • Può essere smaltito, modificato, utilizzato in combinazione con altre classi o utilizzato in qualsiasi altro modo necessario.

  • Poiché non esiste un rilevamento del contesto, non ha alcun significato per Entity Framework.

Stato aggiunto

  • Quando un'entità è nello stato Aggiunto, hai poche opzioni. In effetti, puoi solo staccarlo dal contesto.

  • Naturalmente, anche se modifichi una proprietà, lo stato rimane Aggiunto, perché spostarlo in Modificato, Non modificato o Eliminato non ha senso.

  • È una nuova entità e non ha corrispondenza con una riga nel database.

  • Questo è un prerequisito fondamentale per trovarsi in uno di quegli stati (ma questa regola non è applicata dal contesto).

Stato modificato

  • Quando un'entità viene modificata, significa che era nello stato Non modificato e quindi alcune proprietà sono state modificate.

  • Dopo che un'entità è entrata nello stato Modificato, può passare allo stato Scollegato o Eliminato, ma non può tornare allo stato Non modificato anche se si ripristinano manualmente i valori originali.

  • Non può nemmeno essere modificato in Aggiunto, a meno che non si scolleghi e si aggiunga l'entità al contesto, perché una riga con questo ID esiste già nel database e si otterrebbe un'eccezione di runtime quando viene mantenuta.

Stato eliminato

  • Un'entità entra nello stato Deleted perché era Unchanged o Modified e quindi è stato utilizzato il metodo DeleteObject.

  • Questo è lo stato più restrittivo, perché è inutile passare da questo stato a qualsiasi altro valore tranne Detached.

Il usingse si desidera che tutte le risorse controllate dal contesto vengano eliminate alla fine del blocco. Quando usi il fileusing istruzione, quindi il compilatore crea automaticamente un blocco try / latest e chiama dispose nel blocco latest.

using (var context = new UniContext()) {

   var student = new Student {
      LastName = "Khan", 
      FirstMidName = "Ali", 
      EnrollmentDate = DateTime.Parse("2005-09-01")
   };

   context.Students.Add(student);
   context.SaveChanges();
}

Quando si lavora con un contesto di lunga durata, considerare quanto segue:

  • Man mano che si caricano più oggetti e relativi riferimenti in memoria, il consumo di memoria del contesto può aumentare rapidamente. Ciò potrebbe causare problemi di prestazioni.

  • Ricordarsi di smaltire il contesto quando non è più necessario.

  • Se un'eccezione fa sì che il contesto sia in uno stato irreversibile, l'intera applicazione può terminare.

  • Le possibilità di incorrere in problemi relativi alla concorrenza aumentano con l'aumentare del divario tra il momento in cui i dati vengono interrogati e quelli aggiornati.

  • Quando si lavora con le applicazioni Web, utilizzare un'istanza di contesto per richiesta.

  • Quando si lavora con Windows Presentation Foundation (WPF) o Windows Form, utilizzare un'istanza di contesto per modulo. Ciò consente di utilizzare la funzionalità di rilevamento delle modifiche fornita dal contesto.

Regole pratiche

Web Applications

  • È ormai prassi comune e migliore che per le applicazioni web, il contesto venga utilizzato per richiesta.

  • Nelle applicazioni web trattiamo richieste che sono molto brevi ma trattengono tutte le transazioni del server in cui sono quindi la giusta durata per il contesto in cui vivere.

Desktop Applications

  • Per applicazioni desktop, come Win Forms / WPF, ecc., Il contesto viene utilizzato per modulo / finestra di dialogo / pagina.

  • Poiché non vogliamo avere il contesto come singleton per la nostra applicazione, lo elimineremo quando passeremo da una forma all'altra.

  • In questo modo, acquisiremo molte delle capacità del contesto e non subiremo le implicazioni di contesti di lunga durata.