2

我在项目中实现 SqlDependency 时遇到问题。

我在 WCF 服务中使用 SqlDependency。然后,WCF 服务将所有表的所有结果保存在内存缓存中,以便获得巨大的速度增益。一切似乎都运行良好,除非我正在更新表格行。如果我在表中添加或删除一行,DataContext 会刷新并且缓存会失效而不会出现问题。但是当涉及到表行更新时,什么都没有发生,缓存没有失效,当我在调试模式下查看 DataContext 的内容时,似乎没有任何变化。

这是我正在使用的代码(请注意,我正在使用 System.Runtime.Caching 对象):

public static List<T> LinqCache<T>(this Table<T> query) where T : class
        {
            ObjectCache cache = MemoryCache.Default;

            string tableName = 
                query.Context.Mapping.GetTable(typeof(T)).TableName;
            List<T> result = cache[tableName] as List<T>;

            if (result == null)
            {
                using (SqlConnection conn = 
                    new SqlConnection(query.Context.Connection.ConnectionString))
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand(
                        query.Context.GetCommand(query).CommandText, conn);
                    cmd.Notification = null;
                    cmd.NotificationAutoEnlist = true;

                    SqlDependency dependency = new SqlDependency(cmd);
                    SqlChangeMonitor sqlMonitor = 
                        new SqlChangeMonitor(dependency);

                    CacheItemPolicy policy = new CacheItemPolicy();
                    policy.ChangeMonitors.Add(sqlMonitor);

                    cmd.ExecuteNonQuery();
                    result = query.ToList();
                    cache.Set(tableName, result, policy);
                }
            }
            return result;
        }

我创建了一个扩展方法,所以我所要做的就是查询这样的任何表:

List<MyTable> list = context.MyTable.LinqCache();

我的 DataContext 在 Global.asax 中打开Application_OnStart并存储在缓存中,因此我可以随时在我的 WCF 服务中使用它。以及此时我打开 SqlDependency 对象

SqlDependency.Start(
    ConfigurationManager.ConnectionStrings[myConnectionString].ConnectionString);

那么,这是 SqlDependency 的限制,还是我在此过程中做错了什么/遗漏了什么?

4

1 回答 1

1

我认为问题在于,尽管您完成了设置命令对象的所有工作,但您随后会执行以下操作:

cmd.ExecuteNonQuery();
result = query.ToList();

它将使用您的 SQL 命令并丢弃结果,然后 LINQ to SQL 将通过 query.ToList() 在内部生成它自己的。幸运的是,您可以要求 LINQ to SQL 执行您自己的命令并为您翻译结果,因此请尝试将这两行替换为:

results = db.Translate<T>(cmd.ExecuteReader());
于 2012-02-12T17:54:37.980 回答