小编典典

SQL缓存和实体框架

sql

我整理了一个小型ASP.NET MVC 2站点,该站点进行了一些非常广泛的日期挖掘/ table-joins / etc。

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

  1. 对于与同一操作相同的参数,我使用OutputCacheAttributewith 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原因很简单。理想情况下,我希望缓存窗口更大,但是如果数据库发生更改,则缓存项将过期。

CacheItemPolicy似乎与支持这个ChangeMonitors集合,而我可以添加SqlChangeMonitor,但要建的时候这是我停下来。

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

SqlChangeMonitor是用构造的,SqlDependency它需要一个SqlCommand-如何锁住Entity
Framework对我的数据库的封装?


阅读 158

收藏
2021-04-15

共1个答案

小编典典

可以将任何任意LINQ查询包装在SqlDependency中,包括EF
Linq查询,请参见LinqToCache。但是不幸的是,EF选择为查询创建SQL的方式,即使是最简单的方式from t in context.table select t,也与查询通知限制不兼容,并且SqlDependency作为无效语句立即失效。我已经在LINQ查询的基于SqlDependency的缓存中谈到了这一点。

您可以做的是将SqlChangeMonitor简单的SqlCommand对象与SELECT ... FROM Table可能会更改的表上构造为简单的对象一起使用。您需要了解,设置通知的成本和轮询的成本之间存在平衡,如果您的表频繁更改,则监视更改可能比轮询更昂贵。

2021-04-15