Friday, March 26, 2010

Clearing the cache of a LINQ to SQL DataContext

I was having some problems with my test code in that the DataContext was returning the objects from the cache (even though it was querying the database) and this was skewing my integration tests. Through the use of Reflector I found that there actually is a method for clearing the cache, handily called ClearCache(). However, the method was internal and so could not be called directly from code.

Internal methods are, however, available through reflection (I'm a bit of a noob when it comes to reflection so there might be constraints on when they are and when they aren't but this works for me). In order to make it easy to clear the cache (for example, after saving but before retrieving the object from the database for checking it saved correctly) I have created an extension method to do the heavy lifting for me:


using System.Data.Linq;
using System.Reflection;

namespace MyNamespace
{
public static class Extensions
{
public static void ClearCache(this DataContext context)
{
const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

var method = context.GetType().GetMethod("ClearCache", FLAGS);
method.Invoke(context, null);
}
}
}

//Usage example: (will NOT compile unless you change the Abc below and include it's namespace...)
public class Xyz
{
public void DoWork()
{//'Abc being whatever your particular SQL Metal-generated data context is called
AbcDataContext dataContext = new AbcDataContext("my optional connection string");

//do work...

//check out the 'Extension Method' magic! Now the our custom static method defined above can be called like this:
dataContext.ClearCache();

//do more work...
//take a break...
}
}

No comments:

Post a Comment