从DataContext缓存数据

时间:2011-05-16 04:16:59

标签: asp.net linq-to-sql

我们在Web应用程序中使用Linq-to-SQL DataContext,该应用程序向应用程序提供只读数据,并且永远不会更新(已设置ObjectTrackingEnabled = false以强制执行此操作。

由于数据永远不会改变(除了偶尔的配置更新),因此为每个Web请求使用新的DataContext从SQL Server重新加载它似乎很浪费。

我们尝试在Application对象中缓存DataContext以供所有使用请求,但它产生了很多错误,我们的研究表明这是一个坏主意,DataContext应该在同一工作单元内处理,不是线程安全等等。

因此,由于DataContext是数据访问机制,而不是数据存储,我们需要考虑缓存从中获取的数据,而不是上下文本身。

更愿意使用实体和集合本身来执行此操作,因此代码可以不知道它是处理缓存还是“新鲜”数据。

如何安全地完成这项工作?

首先,在处理DataContext之前,我需要确保实体和集合已完全加载。有没有办法方便地从数据库中强制完全加载所有内容?

其次,我很确定存储对实体和集合的引用是一个坏主意,因为它将

(a)当DataContext超出范围或

时,导致实体被破坏

(b)防止DataContext超出范围

那么我应该克隆EntitySets并存储它们吗?如果是这样,怎么样?或者这里有什么?

2 个答案:

答案 0 :(得分:1)

这不是你问题的答案,但我建议避免在网站方面进行缓存 我更愿意专注于优化数据库查询,以便更快,更有效地进行数据检索。

缓存将:

  • 不可扩展
  • 需要额外的同步代码,我假设您的数据在数据库中不是完全静态的吗?
  • 额外的代码将容易出错
  • 将快速占用您的Web服务器的内存,您可能最终解决的下一件事是您的Web服务器上的内存问题
  • 当您需要对网站进行负载均衡时,
  • 将无法正常运行

<强> [编辑]

如果我需要缓存5MB数据,我会使用Cache对象,可能是延迟加载。我会使用一组轻量级集合,例如ReadonlyCollection<T>Collectino<T>。我也可能会使用ReadonlyDictionary<TKey, TValue>来快速搜索内存。我会使用LINQ-to-Objects来处理集合。

答案 1 :(得分:0)

您希望缓存从DataContext而不是DataContext对象本身检索的数据。我通常会将常用检索的​​数据重构为可以实现静默缓存的方法,比如这样(可能需要添加线程安全逻辑):

public class MyBusinssLayer {

    private List<MyType> _myTypeCache = null;
    public static List<MyType> GetMyTypeList() {
        if (_myTypeCache == null) {
            _myTypeCache = // data retrieved from SQL server
        }

        return _myTypeCache
    }

}

这是最简单的模式,可用于缓存一个Web请求。要进行较长时间的缓存,请将内容存储在较长期的存储空间中,例如ApplicationCache。例如,要存储Application级数据,请使用此类模式。

public static List<MyType> GetMyTypeList() {
    if (Application["MyTypeCacheName"] = null) {
        Application["MyTypeCacheName"] = // data retrieved from SQL server
    }

    return (List<MyType>)Application["MyTypeCacheName"];
}

这适用于几乎不会更改的数据,例如可在DropDownList中选择的静态状态类型集合。对于更多的volitile数据,您可以使用Cache超时期限,应根据数据更改的频率选择。如果需要,可以使用代码手动使Cache个项目无效,或使用SqlCacheDependency等依赖性检查器。

希望这有帮助!