Come forzare Entity Framework a ottenere sempre dati aggiornati dal database?


91

Sto usando la libreria EntityFramework.Extended per eseguire aggiornamenti batch. L'unico problema è che EF non tiene traccia degli aggiornamenti batch eseguiti dalla libreria. Quindi, quando eseguo DbContextnuovamente una query , non restituisce le entità aggiornate.

Ho scoperto che l'utilizzo del AsNoTracking()metodo durante l'interrogazione disabilita il monitoraggio e ottiene nuovi dati dal database. Tuttavia, poiché EF non tiene traccia delle entità interrogate AsNoTracking(), non sono in grado di eseguire alcun aggiornamento sui dati interrogati.

C'è un modo per forzare EF a ottenere i dati più recenti durante il rilevamento delle modifiche?


2
29k visualizzazioni e solo 19 voti positivi su questo ... beh, ho aggiunto il mio comunque
jleach

Risposte:


152

Prova questo per aggiornare una singola entità:

Context.Entry<T>(entity).Reload()

Modifica: per ottenere nuovi dati per una raccolta di entità vale la pena provare a eliminare l' DbContextistanza dopo ogni richiesta.


Grazie! Esiste un modo per ricaricare una raccolta di entità anziché una? Preferibilmente l'intero DbSet.
Saravana

C'è qualcos'altro di cui hai bisogno perché questa sia considerata la risposta?
PlTaylor

1
Sì, ancora non mostra come ricaricare una raccolta di entità.
Saravana

1
Hai provato a eliminare il tuo dbcontext e a crearne uno nuovo?
PlTaylor

3
Mi ci sono volute ore per arrivare a questa conclusione. Quella MODIFICA nella risposta è ciò che mi ha aiutato a trovare la mia soluzione. Grazie!
BeemerGuy

17

Mi sono imbattuto in questa domanda mentre cercavo una soluzione a un problema che stavo riscontrando in cui le proprietà di navigazione non venivano popolate dopo l'aggiornamento dell'entità. Ogni volta che ho tentato di ricaricare l'entità dal database, avrebbe invece catturato la voce dall'archivio locale che non avrebbe popolato le proprietà di navigazione tramite caricamento lento. Invece di distruggere il contesto e ricrearne uno, ho scoperto che questo mi ha permesso di ottenere nuovi dati con i proxy funzionanti:

_db.Entry(entity).State = EntityState.Detached;

La logica alla base era: il mio aggiornamento ha allegato l'entità in modo che ne tenesse traccia delle modifiche. Questo lo aggiunge al negozio locale. Successivamente, qualsiasi tentativo di recuperare l'entità con proxy funzionali comporterebbe che acquisisca quello locale invece di uscire nel database e restituire una nuova entità abilitata per proxy. Ho provato l'opzione di ricarica sopra, che aggiorna l'oggetto dal database, ma questo non ti dà l'oggetto proxy con caricamento lento. Ho provato a fare un file Find(id), Where(t => t.Id = id), First(t => t.Id = id). Infine, ho controllato gli stati disponibili forniti e ho visto che era presente uno stato "Scollegato". Eureka! Spero che questo aiuti qualcuno.


Dove applichi lo stato Scollegato per far funzionare il caricamento lento? Ho provato la tua soluzione e non ha funzionato per me, devo perdere qualcosa. Il tuo aiuto sarebbe apprezzato
Rex

2
L'ho capito: 1. salva l'entità, 2. imposta lo stato su disconnesso, 3. leggi l'entità da db. Grazie per il suggerimento!
Rex

1

L'esecuzione del codice nello stesso contesto non produrrà entità aggiornate. Aggiungerà solo nuove entità create nel database tra le sessioni. Il ricaricamento della forza EF può essere fatto in questo modo:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();

1

Ho dichiarato la variabile entità, senza assegnazione, come parte della classe. Questo mi ha permesso di disporre di un'istanza senza perdere la variabile come riferimento con altri metodi. Mi sono appena imbattuto in questo quindi non ha molto tempo di esecuzione sotto la cintura, ma finora sembra funzionare bene.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}

0

Per me ... accedo al mio DbContext in questo modo:

_viewModel.Repo.Context

Per forzare EF a colpire il database, faccio questo:

_viewModel.Repo.Context = new NewDispatchContext();

Sovrascrittura del DbContext corrente con una nuova istanza. Quindi la prossima volta che utilizzo i miei servizi di dati ottengono i dati dal database.

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.