I have put together a small ASP.NET MVC 2 site that does some very extensive date mining/table-joins/etc.
Using MVC, I have a controller that returns the data in many different forms (tables, images, etc). To save hitting the database frequently I have a dual cache mechanism:
OutputCacheAttribute
with VaryByParam = "*"
. System.Runtime.Caching.ObjectCache
.Example of the ObjectCache
inside of the Controller:
private static readonly ObjectCache cache =
new MemoryCache("CompareControllerCache");
private static void CacheObject(ViewModel obj,
string param1,
int someOtherParam )
{
string key = string.Format("{0}-{1}", param1, someOtherParam);
Trace.WriteLine(string.Format("Adding {0} to the cache", key));
cache.Add(key, obj, new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(1)
});
}
// Corresponding GetCachedObject with similar key defining logic.
This gives me a good performance improvement, but where it fails is on the CacheItemPolicy
being very simple. Ideally, I'd like the cache-window to be bigger but have the cached item expire if the database changes.
The CacheItemPolicy
seems to support this with the ChangeMonitors
collection, to which I could add a SqlChangeMonitor
, but when trying to construct this is where I come to a halt.
I am using Entity Framework 4 to access an SQL Database, how how do I construct the SqlChangeMonitor
to monitor the couple of database tables that are likely to trigger a cache expire?
SqlChangeMonitor
is constructed with an SqlDependency
which takes an SqlCommand
- how can I latch upon Entity Framework's encapsulation of my database?
The first time a query is invoked, data is retrieved from the database and stored in memory before being returned. The compiled queries could be cached for the life of an app pool instance and provided to the Entity Framework for low latency performance of data access.
Entity Framework has the following forms of caching built-in: Object caching – the ObjectStateManager built into an ObjectContext instance keeps track in memory of the objects that have been retrieved using that instance. This is also known as first-level cache.
Caching with Entity Framework NCache introduces the caching provider which acts between Entity Framework and the Data source. The major reason behind the EF Caching provider is to reduce database trips (which slow down application performance) and serve the query result from the cache.
Entity Framework Core does not come with its caching framework (like NHibernate does). However, NCache has developed a very flexible, powerful, and yet very simple caching framework for you.
It is possible to wrap any arbitrary LINQ query in a SqlDependency, including EF Linq queries, see LinqToCache. But unfortunately the way EF chooses to formulate the SQL for the queries, even the most simple from t in context.table select t
, is incompatible with the Query Notificaiton restriction and the SqlDependency is invalidated straight away as an invalid statement. I have talked about this in SqlDependency based caching of LINQ Queries.
What you can do is use SqlChangeMonitor
with straightforward SqlCommand
objects constructed as simple SELECT ... FROM Table
on your tables that are likely to change. You need to understand that there is a balance between the cost of setting up notifications and the cost of polling, if your tables change frequently then monitoring for changes could turn out to be more expensive than polling. See this article The Mysterious Notification to understand how QN works and what is the cost of monitoring.
hi answer with implementation can be found at below site
http://harismile.wordpress.com/2010/09/09/mvc-with-ef-sqldependencycache/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With