Entity Framework Aggiorna contesto?


101

Come potrei aggiornare il mio contesto? Ho entità basate su viste dal mio database e quando ho effettuato un aggiornamento su una tabella Entità che ha proprietà di navigazione per le viste, l'entità viene aggiornata ma la vista non si aggiorna secondo i nuovi aggiornamenti ... voglio solo tornare da il Db i dati. Grazie!

Risposte:


92

Il modo migliore per aggiornare le entità nel tuo contesto è eliminare il tuo contesto e crearne uno nuovo.

Se hai davvero bisogno di aggiornare qualche entità e stai usando l'approccio Code First con la classe DbContext, puoi usare

    public static void ReloadEntity<TEntity>(
        this DbContext context, 
        TEntity entity)
        where TEntity : class
    {
        context.Entry(entity).Reload();
    }

Per ricaricare le proprietà di navigazione della raccolta, puoi usare

    public static void ReloadNavigationProperty<TEntity, TElement>(
        this DbContext context, 
        TEntity entity, 
        Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
        where TEntity : class
        where TElement : class
    {
        context.Entry(entity).Collection<TElement>(navigationProperty).Query();
    }

Riferimento: https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infrastructure.DbEntityEntry .Ricaricare


3
Non riesco a farlo funzionare per ricaricare le proprietà di navigazione figlio.
— Paul,

@David puoi usare context.ReloadNavigationProperty(parent, p => p.Children);se haiclass Parent { ICollection<Child> Children; }
— Jinjinov

In EF Core puoi usare Query (). Load () così, ad esempiocontext.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
— Rubenisme

Non capisco perché questa soluzione sia votata così bene. context.Entry (entity) .Collection <TElement> (navigationProperty) .Query () non ricarica la raccolta figlio. Ti dà solo un Iqueryable che rappresenta la query utilizzata per ottenere la raccolta. Non fa letteralmente nulla.
— statler

72
yourContext.Entry(yourEntity).Reload();

3
Grazie per la semplice soluzione. Non vedo la necessità di incapsulare questo in un metodo di estensione come ha fatto RX_DID_RX
— Thomas

Questo è stato un vero toccasana per me. Grazie!
— Kevin

19
Si noti che questo non ricarica le proprietà di navigazione della raccolta, ma solo la voce dell'entità stessa.
— James Wilkins,

28

Se vuoi ricaricare entità specifiche, con DbContextApi, RX_DID_RX ti ha già dato la risposta.

Se vuoi ricaricare / aggiornare tutte le entità che hai caricato:

Se stai usando Entity Framework 4.1+ (EF5 o EF 6 probabilmente), API DbContext:

public void RefreshAll()
{
     foreach (var entity in ctx.ChangeTracker.Entries())
     {
           entity.Reload();
     }
}

Se stai usando entityFramework 4 (ObjectContext API):

public void RefreshAll()
{
     // Get all objects in statemanager with entityKey
     // (context.Refresh will throw an exception otherwise)
     var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted
                                               | EntityState.Modified
                                               | EntityState.Unchanged)
                                      where entry.EntityKey != null
                                      select entry.Entity);

     context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}

Il miglior consiglio comunque è, cerca di usare un "contesto di breve durata" ed eviterai questo tipo di problemi.

Ho scritto un paio di articoli sull'argomento:

https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/


Ben fatto!! Mi ha salvato la giornata!
— Radu D

15

Usa il metodo Aggiorna :

context.Refresh(RefreshMode.StoreWins, yourEntity);

o in alternativa elimina il tuo contesto attuale e creane uno nuovo.


@JMK Cosa non funziona esattamente qui? Sembra funzionare bene per me (EF 6.1.1).
— Sebastian Krysmanski

@SebastianKrysmanski ho commentato quasi un anno fa, forse è stato corretto da allora?
— JMK

5
Penso che funzioni solo per objectcontext ma non per dbcontext. È necessaria una conversazione tra loro
— batmaci

3
@batmaci Che può essere facilmente fatto con((IObjectContextAdapter)dbContext).ObjectContext
— Daniel Z.

3
Che non è stato dichiarato in modo un po 'incompleto.
— user441521

6

context.Reload () non funzionava per me in MVC 4, EF 5, quindi l'ho fatto.

context.Entry(entity).State = EntityState.Detached;
entity = context.Find(entity.ID);

e funziona bene.


1

EF 6

Nel mio scenario, Entity Framework non stava raccogliendo i dati appena aggiornati. Il motivo potrebbe essere che i dati sono stati aggiornati al di fuori del suo ambito. L'aggiornamento dei dati dopo il recupero ha risolto il mio problema.

private void RefreshData(DBEntity entity)
{
    if (entity == null) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entity);
}

private void RefreshData(List<DBEntity> entities)
{
    if (entities == null || entities.Count == 0) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entities);
}

1
Sono con EF6. Perché questo è meglio di un _context.Entry(entity).Reload();?
— Csaba Toth,

Per quanto posso ricordare, .Reload()non è disponibile in EF6. @CsabaToth
— Mahbubur Rahman

0

L'aggiornamento del contesto del database con Ricarica non è consigliato a causa della perdita di prestazioni. È abbastanza buono e la procedura migliore per inizializzare una nuova istanza di dbcontext prima di ogni operazione eseguita. Fornisce inoltre un contesto aggiornato aggiornato per ciascuna operazione.

using (YourContext ctx = new YourContext())
{
   //Your operations
}

6
Amico ... Scaricare il tuo contesto ogni volta aggiornerà anche le cose che non vuoi vengano aggiornate, il che porterà davvero a problemi di prestazioni.
— LuckyLikey

2
Questa è un'idea terribile in quanto influisce sulla capacità di scrivere test unitari. Se il tuo codice si spegne e le notizie su un nuovo contesto, come funzionerà durante uno unit test?
— vincitore

5
Sarebbe utile per me e per altri se mostrassi alcuni campioni piuttosto che fare critiche.
— AOG

Va bene per piccoli siti web.
— alikuli

-7

Mi sono fatto male alla testa per niente! La risposta è stata molto semplice, sono appena tornato alle basi ...

some_Entities   e2 = new some_Entities(); //your entity.

aggiungi questa riga di seguito dopo aver aggiornato / eliminato: stai ricaricando la tua entità, senza metodi di sistema fantasiosi.

e2 = new some_Entities(); //reset.

2
Questo "funzionerà" - è solo un'idea terribile e avrà altre conseguenze
— Adam Hey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.