How to disable change tracking at the level of DbContext in EF 4.1 RC?

I ran into a problem that seems to be a common problem: I am updating the values ​​in my database, but EF uses the original copy of the object in memory and these changed values ​​are not displayed in the displayed data. I understand why this is so, but I cannot figure out how to do it.

The most common solution is to install MergeOptions.NoTracking to completely turn off change tracking (or use the AsNoTracking() extension method when prompted) and force an update every time the object is accessed, which is great for my purposes.

I have a common base repository that my other repositories inherit from:

 public abstract class RepositoryBase<T> where T : class { private readonly IDbSet<T> _dbset; private readonly IUnitOfWork _unitOfWork; protected RepositoryBase(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; _dbset = _unitOfWork.Database.Set<T>(); } public virtual IQueryable<T> All() { return _dbset; } // Some other IQueryable methods here (Query, GetByProductCode etc) public virtual T Get(long id) { return _dbset.Find(id); } } 

And DbContext :

 public class Db : DbContext { private IDbSet<Product> _products; public IDbSet<Product> Products { get { return _products ?? (_products = DbSet<Product>()); } } public virtual IDbSet<T> DbSet<T>() where T : class { return Set<T>(); } public virtual void Commit() { base.SaveChanges(); } } 

If I change the All() method of my repository this way:

 public virtual IQueryable<T> All() { return _dbset.AsNoTracking(); } 

I get the desired result - the update in the database is reflected when the page displaying the products is updated. However, I cannot do this in the Get() method, since this extension method only works on IQueryable .

Ideally, I would like to disable this at the DbContext level, since I will never need change tracking, but there seems to be no obvious way to do this, and there are quite a lot of null documentation on (if someone cannot tell me someone ? You are welcome!).

I tried adding a constructor to the DbContext with the configuration options disabled:

 public Db() { base.Configuration.ProxyCreationEnabled = false; base.Configuration.AutoDetectChangesEnabled = false; } 

But I have to admit that I only guess what they are actually doing (I just found them by looking at the source code), and they still have no effect.

Any help would be greatly appreciated. If you need additional information / code, let me know.

+7
source share
1 answer

If you want to force the context to receive fresh data every time you do not want to use the Find method. Find method always queries the internal storage. Use this instead:

 public virtual T Get(long id) { return All().SingleOrDefault(e => e.Id == id); } 

But I do not understand what you need? What do you mean by:

the update is displayed in the database when the page displaying the products is updated

Context is a unit of work. It should be used as a unit of work - in a web application or web service, this means creating a new instance of the context for each request. In a winforms / wpf application, this means using context for each logical block (for each host, etc.). Because of this, you only need this in very specific scenarios, but you want it globally. Your description looks like you are reusing context among requests for completely bad decisions . There is no performance overhead in the context of recreation for each request.

+6
source

All Articles