I have an isolated problem with cached data in a web app, and understand that it’s cached due to the way the datacontext is reused. My Repository classes return IQueryable types, so I’m unable to refresh the datacontext by closing & reopening it. For example, my CustomerRepository has this datacontext constructor:
private CAClassesDataContext context = new CAClassesDataContext();
And all database interaction methods then use this context, e.g:
public IQueryable<Customer> Customers
{
get { return context.Customers; }
}
If I try to use the context in a using block:
using(CAClassesDataContext context = new CAClassesDataContext())
{
...
}
I can’t access the related classes as lazy loading is used. I’ve tried adding:
context.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer)
after the update but the problem still exists. How can I force LINQ to SQL to use the database data instead of the cached?
UPDATE:
Thanks to answers provided by Steve & Andrew I was able to resolve the issue. My respositories now have a constructor like this:
[Inject]
public CustomerRepository (CAClassesDataContext Context)
{
context = Context;
}
And in my Ninject bindings added:
Bind<CAClassesDataContext>().ToSelf().InRequestScope();
My project uses a custom membership provider an I was unable to use the above technique due to the provider’s parameterless constructor. To get round this I added methods to the respository which get called before & after the databse lookup:
repository.CreateContext();
var cust = repository.GetAllCustomers().SingleOrDefault(c => c.Username == username);
repository.DisposeContext();
As @Andrew Stephens says, your context object should be being created and used on a per-request basis.
Instead of hard-coding it to be created inside a repository, inject it into the repository via its constructor. If you’re using an IoC container you may have the ability to have the context managed on a per-request basis for you (Ninject provides this, for example), otherwise you can wrap your context in a request-scoped data store object using
HttpContext.Items, as detailed in this article.