Rilevamento automatico delle modifiche

Quando si usano la maggior parte delle entità POCO, la determinazione del modo in cui un'entità è cambiata (e di conseguenza quali aggiornamenti devono essere inviati al database) viene gestita dall'algoritmo Rileva modifiche. Rilevare le modifiche funziona rilevando le differenze tra i valori correnti delle proprietà dell'entità e i valori delle proprietà originali archiviati in uno snapshot quando l'entità è stata sottoposta a query o associata. Le tecniche illustrate in questo argomento si applicano in modo analogo ai modelli creati con Code First ed EF Designer.

Per impostazione predefinita, Entity Framework esegue rileva modifiche automaticamente quando vengono chiamati i metodi seguenti:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Add
  • DbSet.AddRange
  • DbSet.Remove
  • DbSet.RemoveRange
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Disabilitazione del rilevamento automatico delle modifiche

Se si rilevano molte entità nel contesto e si chiama uno di questi metodi molte volte in un ciclo, è possibile ottenere miglioramenti significativi delle prestazioni disattivando il rilevamento delle modifiche per la durata del ciclo. Ad esempio:

using (var context = new BloggingContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;

        // Make many calls in a loop
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}

Non dimenticare di riabilitare il rilevamento delle modifiche dopo il ciclo. È stato usato un tentativo/finally per assicurarsi che sia sempre riabilitato anche se il codice nel ciclo genera un'eccezione.

Un'alternativa alla disabilitazione e alla ripetizione dell'abilitazione consiste nel lasciare disattivato sempre il rilevamento automatico delle modifiche e di entrambi i contesti di chiamata. ChangeTracker.DetectChanges in modo esplicito o usare i proxy di rilevamento delle modifiche in modo diligente. Entrambe queste opzioni sono avanzate e possono introdurre facilmente bug sottili nell'applicazione in modo da usarle con cura.

Se è necessario aggiungere o rimuovere molti oggetti da un contesto, è consigliabile usare DbSet.AddRange e DbSet.RemoveRange. Questi metodi rilevano automaticamente le modifiche una sola volta dopo il completamento delle operazioni di aggiunta o rimozione.