SqlDependency和表更新不刷新DataContext

时间:2010-11-04 19:25:38

标签: linq-to-sql c#-4.0 sqldependency

我在项目中执行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的限制,还是我在做错了什么/错过了什么?

1 个答案:

答案 0 :(得分:1)

我认为问题在于,尽管您在设置命令对象方面做了所有工作,但您仍然可以:

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

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

results = db.Translate<T>(cmd.ExecuteReader());