实体框架4和查询结果的缓存

时间:2011-06-21 06:18:29

标签: c# caching entity-framework-4

假设我有一个表或2包含永远或很少更改的数据,是否有任何尝试缓存这些数据的点?或者,当我第一次加载数据时,EF上下文会为我缓存该数据吗?我正在考虑从这些表加载所有数据并使用静态列表或其他东西将数据保存在内存中,并在我需要同一上下文中的数据时查询内存数据而不是表。我所说的那些表通常包含几百行数据。

3 个答案:

答案 0 :(得分:21)

EF上下文将缓存“每个实例”。也就是说,DbContext的每个实例都保留了它自己独立的对象缓存。您可以将生成的对象列表存储在静态列表中,并在不返回数据库的情况下查询所有内容。为安全起见,请确保在执行查询后放弃DbContext

var dbContext = new YourDbContext();
StaticData.CachedListOfThings = dbContext.ListOfThings.ToList();

稍后您可以使用LINQ查询静态列表。

var widgets = StaticData.CachedListOfThing.Where(thing => thing.Widget == "Foo");

查询执行内存中集合,而不是数据库。

答案 1 :(得分:12)

您可以检查EF caching provider但请注意,这种方式的缓存严格按查询执行 - 因此您必须始终使用相同的查询来获取缓存数据。如果您使用另一个查询,它将首先执行以被视为缓存,然后再次使用它来命中缓存。如果您想避免这种情况并缓存数据,并且能够在缓存集合上运行任何查询,则必须使用自己的解决方案(只需将数据加载到列表中并将其保存在某处)。将实体加载到缓存列表时,请确保关闭代理创建(延迟加载和更改跟踪)。

每个上下文实例的缓存确实有效,但使用上下文本身作为缓存是非常糟糕的选择 - 在大多数情况下我称之为EF反模式。 Use context as unit of work =不要将上下文重用于多个逻辑操作。

答案 2 :(得分:1)

你必须为任何ef4 linq查询滚动自己,因为它们总是被解析为sql,因此总是会命中db。您的情侣表的简单缓存可能不难写。

如果您要通过id进行查询,可以使用ObjectContext.GetObjectByKey method,它会在查询数据库之前查看对象缓存。