Dot-Net

SQL 記憶體和實體框架

  • October 22, 2010

我已經建立了一個小型 ASP.NET MVC 2 站點,該站點進行了一些非常廣泛的日期探勘/表連接/等。

使用 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- 我如何才能鎖定實體框架對我的數據庫的封裝?

可以在 SqlDependency 中包裝任意 LINQ 查詢,包括 EF Linq 查詢,請參閱LinqToCache。但不幸的是,EF 選擇為查詢制定 SQL 的方式,即使是最簡單的from t in context.table select t,也與 Query Notificaiton 限制不兼容,並且 SqlDependency 作為無效語句立即失效。我在基於 SqlDependency 的 LINQ Queries 記憶體中談到了這一點。

您可以做的是使用SqlChangeMonitor簡單的對象,這些對像在您的表上SqlCommand構造得非常簡單,這些對象可能會發生變化。SELECT ... FROM Table您需要了解設置通知的成本和輪詢的成本之間存在平衡,如果您的表經常更改,那麼監控更改可能會比輪詢更昂貴。請參閱這篇文章The Mysterious Notification以了解 QN 的工作原理以及監控成本是多少。

引用自:https://stackoverflow.com/questions/3568178