3

ビューとプロシージャで SqlCacheDependency を使用したいと考えています。

Linq to Sqlを使用しています。

現在使用しているコードは、単一テーブルを使用している場合にのみ有効です:

public static List<T> LinqCache<T>(this System.Linq.IQueryable<T> q, System.Data.Linq.DataContext dc, string CacheId)
{
   try
   {
      List<T> objCache = (List<T>)System.Web.HttpRuntime.Cache.Get(CacheId);

      if (objCache == null)
      {
         /////////No cache... implement new SqlCacheDependeny//////////
         //1. Get connstring from DataContext
         string connStr = dc.Connection.ConnectionString;

         var c = System.Web.Caching.SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connStr);

         //2. Get SqlCommand from DataContext and the LinqQuery
         string sqlCmd = dc.GetCommand(q).CommandText;

         //3. Create Conn to use in SqlCacheDependency
         using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr))
         {
            conn.Open();
            //4. Create Command to use in SqlCacheDependency
            using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sqlCmd, conn))
            {
               //5.0 Add all parameters provided by the Linq Query
               foreach (System.Data.Common.DbParameter dbp in dc.GetCommand(q).Parameters)
               {
                  cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter(dbp.ParameterName, dbp.Value));
               }

               //5.1 Enable DB for Notifications... Only needed once per DB...
               System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(connStr);

               //5.2 Get ElementType for the query
               string NotificationTable = q.ElementType.Name;

               //5.3 Enable the elementtype for notification (if not done!)
               if (!System.Web.Caching.SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connStr).Contains(NotificationTable))
                  System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(connStr, NotificationTable);

               //6. Create SqlCacheDependency
               System.Web.Caching.SqlCacheDependency sqldep = new System.Web.Caching.SqlCacheDependency(cmd);
               // - removed 090506 - 7. Refresh the LinqQuery from DB so that we will not use the current Linq cache
               // - removed 090506 - dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, q);
               //8. Execute SqlCacheDepency query...
               cmd.ExecuteNonQuery();
               //9. Execute LINQ-query to have something to cache...
               objCache = q.ToList();
               //10. Cache the result but use the already created objectCache. Or else the Linq-query will be executed once more...
               System.Web.HttpRuntime.Cache.Insert(CacheId, objCache, sqldep);
            }
         }
      }
      //Return the created (or cached) List
      return objCache;
   }
   catch (Exception ex)
   {
     throw ex;
   }
}

ここで、ビュー (複数のテーブル) に sqlcachedependency を実装したいと考えています。

このクエリを使用しようとしています

System.Web.Caching.SqlCacheDependency
dep1 = new System.Web.Caching.SqlCacheDependency(cmd1),
dep2 = new System.Web.Caching.SqlCacheDependency(cmd2);

System.Web.Caching.AggregateCacheDependency aggDep = new System.Web.Caching.AggregateCacheDependency();
aggDep.Add(dep1, dep2);

dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, q);
cmd.ExecuteNonQuery();
objCache = q.ToList();
System.Web.HttpRuntime.Cache.Insert(CacheId, objCache, aggDep);

ただし、基になるテーブルを変更してもキャッシュが無効にならないため、このクエリは機能しません。

あまりにも長い間グーグル検索しましたが、ビューとプロシージャまたは複数のテーブルで機能するコードが見つかりません。

4

1 に答える 1

1

テーブル ベースの通知を使用する場合、別の SqlCommand スタイルのクエリを発行する必要はありません。ExecuteNonQuery と関連するコードは冗長です。作成した AggregateCacheDependency を使用して LINQ の結果を追加するだけです。

テーブルベースの変更通知を完全に有効にしましたか? DB に作成する必要があるテーブル、いくつかのトリガー、およびストアド プロシージャと、定期的なポーリングをトリガーするためのサーバー上のコードがあります。キャッシュの有効期限が切れていないことを宣言する前に、ポーリングが行われるまで十分に待機してください。

変更テーブルの内容を自分で見て、変更が DB 側で取得されているかどうかを確認することもできます。

SELECT * FROM [dbo].[AspNet_SqlCacheTablesForChangeNotification]

1 つのテーブルからの変更が機能している場合は、コードを少し簡略化するために、代わりに SqlCacheDependency.CreateOutputDependency(stringdependency) を使用してみてください。引数は、「DdName:TableName;DbName:TableName」の形式の 1 つ以上のテーブルのリストです。DbName は web.config から取得されます。

以上のことから、テーブルベースの変更通知は非推奨であり、新しいコードでは代わりに Service Broker 通知を使用する必要があることも指摘しておく必要があります。はい、LINQ で動作させることができます。

于 2011-12-03T00:38:36.207 に答える