2016-03-21 10 views
1

Ich verwende EF 6.1.3 und Oracle. Es gibt zwei Sitzungen. In der ersten Sitzung kann ich die aktualisierten Werte der zweiten Sitzung nicht anzeigen.Entity Framework kann die aktualisierten Werte anderer Sitzungen nicht sehen

using (var uow = new DmsUOW() 
{ 
    var var1 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; // var1 = ADMIN5 
    //I change my data ADMIN5-> ADMIN6 from other session(TOAD) and commit. 
    var var2 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; //var1 = ADMIN5 ---> WRONG!!! it must be ADMIN6 
} 

Repository:

public class DmsUOW : UnityOfWorkEF 
    { 
     private ROLE_TYPE_Repository _roleTypeRepository; 
     public ROLE_TYPE_Repository RoleTypeRepository 
     { 
      get { return _roleTypeRepository ?? (_roleTypeRepository = new ROLE_TYPE_Repository(this)); } 
     } 
    } 

RepositoryEf Klasse:

public class RepositoryEf<TEntity> :BaseRepositoryEf, IRepository<TEntity> where TEntity : class 
{ 

    protected DbSet<TEntity> objectSet; 

    public virtual IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> expression) 
    { 
     return objectSet.Where(expression).AsQueryable<TEntity>(); 
    } 
} 

myDbContext Einstellungen:

Configuration.LazyLoadingEnabled = false; 
Configuration.ProxyCreationEnabled = false; 
Configuration.ValidateOnSaveEnabled = false; 

Aber wenn ich SQL-Abfrage schreiben Es funktioniert:

using (var uow = new DmsUOW() 
{ 
    var var1 = uow.RoleTypeRepository.GetMyQuery(3).Single().NAME; 
    var var2 = uow.RoleTypeRepository.GetMyQuery(3).Single().NAME; 
} 

RoleTypeRepository:

public class ROLE_TYPE_Repository : RepositoryEf<ROLE_TYPE> 
{ 
    public ROLE_TYPE_Repository(IUnityOfWork UnityOfWork) : base(UnityOfWork) { } 

    public List<ROLE_TYPE> GetMyQuery(int? id) 
    { 
     return this.Query<ROLE_TYPE>("SELECT * FROM ROLE_TYPE WHERE id = :p1", new OracleParameter("p1", id)).ToList(); 
    } 
} 

Antwort

2

Ja, ein DbContext Caches durch seine Standardwerte, wenn sie aus der Datenbank gelesen werden (Sie alle zwischengespeicherten Instanzen in der DbContext.Set<EntityType>().Local Sammlung finden, und ein DbContext prüft die Local Sammlung, bevor Sie einen Befehl an die Datenbank Ausgabe)

Sie haben mehrere Möglichkeiten:

  1. Verwenden Sie eine neue DbContext Instanz. Dies sollte der bevorzugte Weg sein ... DbContext Instanzen sollen nicht langlebig sein (viel weniger, wenn Sie das Arbeitseinheitsmuster verwenden, das Sie für Ihren Kontextvariablennamen verwenden)
  2. Aktualisieren Sie die Unternehmen aus der Datenbank, bevor es mit:

    var var1 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; 
    // Refresh before reading it 
    uow.Entry(var1).Reload(); 
    var var2 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; 
    
  3. Nehmen sie Ihre Einheit, bevor sie wieder zu lesen:

    var var1 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; 
    // Detach before reading it 
    ((IObjectContextAdapter)uow).ObjectContext.Detach(var1); 
    var var2 = uow.RoleTypeRepository.Get(p => p.ID == 3).Single().NAME; 
    
  4. nicht Ihre Entitäten sie verfolgen, damit sie nicht gecached erhalten:

+0

Ausgezeichnet. Ich habe 4. gewählt. Außerdem speichert sogar es die Werte, die es die Abfrage an DB sendet. Wir haben Sitzungsanfragen verfolgt. Warum macht es so? Übrigens hat AsNoTracking keine Find-Methode? Wie kann ich es implementieren? öffentliche virtuelle TEntity GetByID (Objekt-ID) { Rückgabe objectSet.AsNoTracking(). Suchen (id); } –

+0

@AdemAyg aus Leistungsgründen: das Senden einer Abfrage an den Speicher/die Datenbank ist (in der Regel) viel teurer als das Überprüfen einer In-Memory-Auflistung. – Jcl

+0

Außerdem speichert es sogar die Werte, die es die Abfrage an DB sendet. Wir haben Sitzungsanfragen verfolgt. Warum macht es so? 2. Frage: y Wie hat AsNoTracking keine Find-Methode? Wie kann ich es implementieren? öffentliche virtuelle TEntity GetByID (Objekt-ID) {return objectSet.AsNoTracking(). Suchen (id); } - @Jcl –

Verwandte Themen