我们在Web应用程序中使用Linq-to-SQL DataContext,该应用程序向应用程序提供只读数据,并且永远不会更新(已设置ObjectTrackingEnabled = false以强制执行此操作。
由于数据永远不会改变(除了偶尔的配置更新),因此为每个Web请求使用新的DataContext从SQL Server重新加载它似乎很浪费。
我们尝试在Application对象中缓存DataContext以供所有使用请求,但它产生了很多错误,我们的研究表明这是一个坏主意,DataContext应该在同一工作单元内处理,不是线程安全等等。
因此,由于DataContext是数据访问机制,而不是数据存储,我们需要考虑缓存从中获取的数据,而不是上下文本身。
更愿意使用实体和集合本身来执行此操作,因此代码可以不知道它是处理缓存还是“新鲜”数据。
如何安全地完成这项工作?
首先,在处理DataContext之前,我需要确保实体和集合已完全加载。有没有办法方便地从数据库中强制完全加载所有内容?
其次,我很确定存储对实体和集合的引用是一个坏主意,因为它将
(a)当DataContext超出范围或
时,导致实体被破坏(b)防止DataContext超出范围
那么我应该克隆EntitySets并存储它们吗?如果是这样,怎么样?或者这里有什么?
答案 0 :(得分:1)
这不是你问题的答案,但我建议避免在网站方面进行缓存
我更愿意专注于优化数据库查询,以便更快,更有效地进行数据检索。
缓存将:
<强> [编辑] 强>
如果我需要缓存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请求。要进行较长时间的缓存,请将内容存储在较长期的存储空间中,例如Application
或Cache
。例如,要存储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
等依赖性检查器。
希望这有帮助!