SQL缓存和实体框架

时间:2010-08-25 16:32:21

标签: .net sql asp.net-mvc entity-framework caching

我已经组建了一个小型ASP.NET MVC 2站点,该站点执行一些非常广泛的日期挖掘/表连接/等。

使用MVC,我有一个控制器,它以许多不同的形式(表格,图像等)返回数据。为了节省频繁访问数据库,我有一个双缓存机制:

  1. 对于相同操作的相同参数,我使用OutputCacheAttributeVaryByParam = "*"
  2. 假设操作的某些参数已更改(或调用其他操作),我的“数据”仍可能先前已被请求,因此我在数据库第一次命中后将数据存储在视图模型中,我用.NET 4.0 System.Runtime.Caching.ObjectCache实现了这一点。
  3. Controller内部ObjectCache的示例:

    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.
    

    这给我带来了良好的性能提升,但失败的地方CacheItemPolicy非常简单。理想情况下,我希望缓存窗口更大,但如果数据库发生更改,缓存项目将会过期。

    CacheItemPolicy似乎支持ChangeMonitors集合,我可以添加SqlChangeMonitor,但在尝试构建时,我会停下来。

    我正在使用Entity Framework 4访问SQL数据库,如何构建SqlChangeMonitor来监视可能触发缓存过期的几个数据库表? < / p>

    SqlChangeMonitor使用SqlDependency构建,其中SqlCommand - 如何锁定实体框架对数据库的封装?

2 个答案:

答案 0 :(得分:7)

可以在SqlDependency中包装任意LINQ查询,包括EF Linq查询,请参阅LinqToCache。但不幸的是,EF选择为查询制定SQL的方式,即使是最简单的from t in context.table select t,也与Query Notificaiton限制不兼容,并且SqlDependency会立即作为无效语句失效。我已经在SqlDependency based caching of LINQ Queries中讨论了这个问题。

您可以做的是使用SqlChangeMonitor在您的桌子上构建为简单SqlCommand的简单SELECT ... FROM Table对象,这些对象可能会发生变化。您需要了解设置通知的成本和轮询成本之间的平衡,如果您的表经常更改,那么监视更改可能会比轮询更昂贵。请参阅此文The Mysterious Notification以了解QN的工作原理以及监控的成本。

答案 1 :(得分:2)