c# - net - entity framework clear cache




Problema di memorizzazione nella cache di Entity Framework (7)

Quando si utilizza EF, per impostazione predefinita carica ogni entità solo una volta per contesto. La prima query crea un'istanza di entità e la memorizza internamente. Qualsiasi query successiva che richiede un'entità con la stessa chiave restituisce questa istanza memorizzata. Se i valori nell'archivio dati sono modificati, si riceve comunque l'entità con i valori della query iniziale

Una risposta attenta:

https://stackoverflow.com/a/3653392/1863179

Sono nuovo in Entity Framework.

Ho raggiunto alcuni valori nel mio database usando EF. Ritorna perfettamente e i valori sono mostrati nelle etichette. Ma quando elimino tutti i valori nella mia tabella (senza usare EF), la query EF restituisce i miei vecchi valori. So che l'EF memorizza i valori nella cache e restituisce i dati memorizzati nella cache per le esecuzioni successive. È corretto?

Quindi, come posso risolvere il problema quando ho cancellato tutti i valori nel mio database, ma EF restituisce i vecchi valori?

Modifica :

Ora ho usato datamodel.SaveChanges() . Ma ora restituisce gli stessi vecchi valori.

La mia query di esempio è simile a quanto segue:

SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities();
datamodel.SaveChanges();
List<Compliance> compliance=new List<Compliance>();
IList<ComplianceModel> complianceModel;
if (HttpContext.Current.User.IsInRole("SuperAdmin"))
{
    compliance = datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList();
}

Coppia cose che puoi fare.

  1. Usa un nuovo contesto. Le entità memorizzate nella cache sono memorizzate nel contesto. L'utilizzo di un nuovo contesto gli impedisce di utilizzare la cache.
  2. Se vuoi davvero un contesto globale / di lunga durata, hai due opzioni secondarie: a.) Chiama sempre il metodo Ricarica. db.Entry (entity) .Reload () ... questo costringe il contesto a ricaricare quell'entità. b.) utilizzare un oggetto SqlDependency per rilevare quando i record cambiano e ricaricare le entità secondo necessità. https://code.msdn.microsoft.com/How-to-use-SqlDependency-5c0da0b3

Il codice sottostante ha aiutato il mio oggetto ad essere aggiornato con nuovi valori di database. Il comando Entry (oggetto) .Reload () forza l'oggetto a richiamare i valori del database

GM_MEMBERS member = DatabaseObjectContext.GM_MEMBERS.FirstOrDefault(p => p.Username == username && p.ApplicationName == this.ApplicationName);
DatabaseObjectContext.Entry(member).Reload();

Penso che dovresti seguire alcune delle altre soluzioni qui, ma sembra che tu voglia cancellare la cache. È possibile ottenere ciò facendo quanto segue:

var count = datamodel.Compliances.Local.Count; // number of items in cache (ex. 30)

datamodel.Compliances.Local.ToList().ForEach(c => {
    datamodel.Entry(c).State = EntityState.Detached;
});

count = datamodel.Compliances.Local.Count; // 0

Per prima cosa non suggerirei di modificare il database esterno al tuo sistema a meno che tu non stia facendo solo test e sviluppo.

EF DbContext contiene un'interfaccia IDisposable. Per rilasciare qualsiasi dato memorizzato nella cache, effettuare le chiamate Dispose manualmente o posizionare l'oggetto del database all'interno di un blocco.

        using (SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities())
        {
            List<Compliance> compliance = new List<Compliance>();
            IList<ComplianceModel> complianceModel;
            if (HttpContext.Current.User.IsInRole("SuperAdmin"))
            {
                compliance = datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList();
            }
        }

Ciò assicurerà che il contesto sia cancellato e ricreato la prossima volta che viene utilizzato. Assicurati di farlo per tutte le tue chiamate e non solo per quelle con cui hai problemi.


Se sai che le modifiche sono avvenute all'esterno di EF e desideri aggiornare il tuo ctxt per un'entità specifica, puoi chiamare ObjectContext.Refresh

datamodel.Refresh(RefreshMode.StoreWins, orders);

Se questo sembra essere un problema comune, dovresti disabilitare la memorizzazione nella cache degli oggetti nelle tue query:

SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities();
datamodel.tblCities.MergeOption = MergeOption.NoTracking; 

o per disattivare la memorizzazione nella cache a livello di oggetto per entità specifica,

Context.Set<Compliances>().AsNoTracking();

Ti consiglio di utilizzare MergeOption su tutti EntitieSet dopo aver creato il contesto, in questo modo:

var objSetProps = ctx.GetType().GetProperties().Where(prop => prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(ObjectSet<>));
foreach (PropertyInfo objSetProp in objSetProps)
{
    ObjectQuery objSet = (ObjectQuery)objSetProp.GetValue(ctx, BindingFlags.GetProperty, null, null, null);
    objSet.MergeOption = MergeOption.PreserveChanges;
}

Leggi qui su MergeOption: http://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx Userò NoTracking, credo.

Ma, ti piacerebbe cancellare le entità "nascoste", staccandole.

var entidades = Ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
foreach (var objectStateEntry in entidades)
    Ctx.Detach(objectStateEntry.Entity);

Dove Ctx sono il mio contesto.





catch-all