SQL Caching and Entity Framework

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:

  1. For identical parameters to the same action I use the OutputCacheAttribute with VaryByParam = "*".
  2. Assuming some parameter to the action has changed (or another action is called), it is still possible that my "data" has previously been requested, so I store the data in a view model after the first hit of the database, I achieve this with a .NET 4.0 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?

8
задан John Farrell 25 August 2010 в 16:38
поделиться

1 ответ

Можно обернуть любой произвольный запрос LINQ в SqlDependency, включая запросы EF Linq, см. LinqToCache . Но, к сожалению, способ, которым EF выбирает формулировку SQL для запросов, даже самый простой from t в context.table select t , несовместим с ограничением Query Notificaiton, и SqlDependency сразу аннулируется как недействительный утверждение. Я говорил об этом в Кэширование запросов LINQ на основе SqlDependency .

Что вы можете сделать, так это использовать SqlChangeMonitor с простыми SqlCommand объектами, построенными как простые SELECT ... FROM Table в ваших таблицах, которые могут измениться. Вы должны понимать, что существует баланс между стоимостью настройки уведомлений и стоимостью опроса: если ваши таблицы часто меняются, то мониторинг изменений может оказаться более дорогостоящим, чем опрос. См. Статью Таинственное уведомление , чтобы понять, как работает QN и какова стоимость мониторинга.

7
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: