4

我读过的几乎每个教程似乎都错误地设置了SqlCacheDependency。我相信他们通常会将过时的轮询方法与查询通知方法混为一谈。

以下是众多示例中的两个:


根据我的测试,如果您使用的是代理(MSSQL 2015+),则不需要进行任何.config更改,也不需要进行任何 SqlCacheDependencyAdmin 调用(不需要定义表等)。

我简化只是这样做......

SqlDependency.Start(connString)
...
queryString = "SELECT ...";
cacheName = "SqlCache" + queryString.GetHashCode();
...
using (var connection = new SqlConnection(connString))
{
    connection.Open();
    var cmd = new SqlCommand(queryString, connection)
    {
        Notification = null, 
        NotificationAutoEnlist = true
    };

    var dependency = new SqlCacheDependency(cmd);

    SqlDataReader reader = cmd.ExecuteReader();
    try
    {
        while (reader.Read())
        {
            // Set the result you want to cache
            data = ...
        }
    }
    finally
    {
        reader.Close();
    }

    HostingEnvironment.Cache.Insert(cacheName, data, dependency);
}

(不包括检查缓存是否为空的代码,因为这只是设置。我只想显示缓存的设置)

这似乎无需定义查询中涉及哪些表并在每个表上进行复杂的触发器即可工作。它只是工作。

更令我惊讶的是,查询规则有通知:

  • 创建通知查询(找不到比 2008 年更新的文档)似乎不适用。我打算在我的 SQL 中做一个 TOP 并且它仍然有效。

对于测试,我让它运行一个查询 1000 次,涉及一个名为“设置”的表。然后我更新表中的值并重复查询。

我在 Profiler 中查看任何涉及“设置”一词的查询,我看到查询只执行了 1 次(以设置缓存),然后发生更新语句,然后再次重新执行查询(缓存已失效,查询再次运行)

我担心在 2-3 个小时的努力中寻找正确的方法来做到这一点,我错过了一些东西,真的就这么简单吗?

我真的可以只输入我想要的任何查询并且它会起作用吗?我正在寻找我正在做一些危险/非标准的事情的任何指示,或者我遗漏的任何小字体

4

2 回答 2

1

var 依赖 = 新的 SqlCacheDependency(cmd); 当您编写这样的查询时,您会在其中自动定义表名。您的连接已经有数据库名称。这是非明确的方式来做同样的事情。

捕获异常并知道出了什么问题的显式方法是这样的。

// Declare the SqlCacheDependency instance, SqlDep. 
        SqlCacheDependency SqlDep = null; 

        // Check the Cache for the SqlSource key. 
        // If it isn't there, create it with a dependency 
        // on a SQL Server table using the SqlCacheDependency class. 
        if (Cache["SqlSource"] == null) { 

            // Because of possible exceptions thrown when this 
            // code runs, use Try...Catch...Finally syntax. 
            try { 
                // Instantiate SqlDep using the SqlCacheDependency constructor. 
                SqlDep = new SqlCacheDependency("Northwind", "Categories"); 
            } 

            // Handle the DatabaseNotEnabledForNotificationException with 
            // a call to the SqlCacheDependencyAdmin.EnableNotifications method. 
            catch (DatabaseNotEnabledForNotificationException exDBDis) { 
                try { 
                    SqlCacheDependencyAdmin.EnableNotifications("Northwind"); 
                } 

                // If the database does not have permissions set for creating tables, 
                // the UnauthorizedAccessException is thrown. Handle it by redirecting 
                // to an error page. 
                catch (UnauthorizedAccessException exPerm) { 
                    Response.Redirect(".\\ErrorPage.htm"); 
                } 
            } 

            // Handle the TableNotEnabledForNotificationException with 
            // a call to the SqlCacheDependencyAdmin.EnableTableForNotifications method. 
            catch (TableNotEnabledForNotificationException exTabDis) { 
                try { 
                    SqlCacheDependencyAdmin.EnableTableForNotifications("Northwind", "Categories"); 
                } 

                // If a SqlException is thrown, redirect to an error page. 
                catch (SqlException exc) { 
                    Response.Redirect(".\\ErrorPage.htm"); 
                } 
            } 

            // If all the other code is successful, add MySource to the Cache 
            // with a dependency on SqlDep. If the Categories table changes, 
            // MySource will be removed from the Cache. Then generate a message 
            // that the data is newly created and added to the cache. 
            finally { 
                Cache.Insert("SqlSource", Source1, SqlDep); 
                CacheMsg.Text = "The data object was created explicitly."; 

            } 
        } 

        else { 
            CacheMsg.Text = "The data was retrieved from the Cache."; 
        }
于 2019-07-03T15:49:36.080 回答
0

https://docs.microsoft.com/en-us/dotnet/api/system.web.caching.sqlcachedependency?view=netframework-4.8中所述“使用带有 SQL Server 2005 查询通知的 SqlCacheDependency 对象不需要任何显式配置。”

因此,CMD 中有明确的表名,并且 ADO.net 正在为您发出正确的 Service Broker 配置命令。更新表时,SQL Server 会发布一条 Service Broker 消息,说明表已更新。当 ADO.net 验证 CMD 时,它会检查代理中的显式表以获取更新。

这就是 SQlCacheDependency 关联的 CMD 必须使用显式表的原因。

于 2019-07-04T22:05:15.997 回答