2016-03-21 26 views
1

我使用EF 6.1.3和Oracle。有兩個會話。在第一次會議中,我無法查看 第二屆會議的更新值。實體框架無法看到其他會話的更新值

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 
} 

庫:

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

RepositoryEf類:

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設置:

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

但是,當我寫的SQL查詢它工作正常:

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(); 
    } 
} 

回答

2

是,當他們從數據庫中讀取一個DbContext緩存默認情況下它的值(你會發現DbContext.Set<EntityType>().Local集合中的所有緩存的情況下,和一個DbContext將檢查發出命令到數據庫)

Local收集您有幾種選擇:

  1. 使用新的DbContext實例。這應該是首選的方式... DbContext實例並不意味着長壽命(如果使用工作單位模式,那麼對於您的上下文變量名稱,您使用的模式要少得多)
  2. 刷新從數據庫實體使用它之前:

    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. 再次閱讀它之前分離的實體:

    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. 不要跟蹤你的實體,使他們沒有得到緩存:

    var var1 = uow.RoleTypeRepository.AsNoTracking().Get(p => p.ID == 3).Single().NAME; 
    // Something has changed the item 
    var var2 = uow.RoleTypeRepository.AsNoTracking().Get(p => p.ID == 3).Single().NAME; 
    
+0

非常好。我選擇了4. 除了它緩存它將查詢發送到數據庫的值。我們跟蹤會話查詢。它爲什麼這樣做? 順便說一句AsNoTracking沒有Find方法?我怎樣才能實現它? (object)ID return objectSet.AsNoTracking()。Find(id); } –

+0

@AdemAyg由於性能方面的原因:向存儲/數據庫發送查詢(通常)的方式比僅檢查內存中的集合更昂貴。 – Jcl

+0

除了緩存它將查詢發送到數據庫的值。我們跟蹤會話查詢。它爲什麼這樣做? 2.問題:AsNoTracking沒有Find方法嗎?我怎樣才能實現它? public virtual TEntity GetByID(object id){return objectSet.AsNoTracking()。Find(id); } - @Jcl –