代码之家  ›  专栏  ›  技术社区  ›  Ray Hayes

SQL缓存和实体框架

  •  8
  • Ray Hayes  · 技术社区  · 14 年前

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

    使用MVC,我有一个控制器,它以许多不同的形式(表、图像等)返回数据。要经常保存命中数据库的操作,我有一个双缓存机制:

    1. 对于相同操作的相同参数,我使用 OutputCacheAttribute 具有 VaryByParam = "*" .
    2. 假设操作的某个参数已更改(或调用了另一个操作),则仍有可能以前已请求过我的“数据”,因此在第一次命中数据库后,我将数据存储在视图模型中,并使用.NET 4.0实现这一点。 System.Runtime.Caching.ObjectCache .

    实例 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 非常简单。理想情况下,我希望缓存窗口更大,但如果数据库更改,缓存项将过期。

    这个 高速缓存策略 似乎支持这个 ChangeMonitors 集合,我可以向其中添加 SqlChangeMonitor 但当我试图建造时,这就是我停止的地方。

    我正在使用Entity Framework 4访问SQL数据库,如何 我如何构建 更改监视器 要监视可能触发缓存过期的两个数据库表吗?

    更改监视器 是用 SqlDependency 这需要一个 SqlCommand -我如何才能锁定实体框架对我的数据库的封装?

    2 回复  |  直到 14 年前
        1
  •  7
  •   Remus Rusanu    14 年前

    可以在sqlDependency中包装任意的linq查询,包括ef linq查询,请参见 LinqToCache . 但不幸的是,EF选择为查询制定SQL的方式,即使是最简单的 from t in context.table select t ,与查询通知约束不兼容,并且sqlDependency作为无效语句立即失效。我已经在 SqlDependency based caching of LINQ Queries .

    你能做的就是利用 SqlChangeMonitor 直截了当 SqlCommand 对象构造为简单 SELECT ... FROM Table 在你可能会改变的桌子上。您需要了解,在设置通知的成本和轮询的成本之间有一个平衡,如果您的表经常更改,那么监视更改可能比轮询更昂贵。看这篇文章 The Mysterious Notification 了解QN的工作原理和监控成本。

        2
  •  2
  •   hari    14 年前