我们的系统使用EF 6(Code First)和
MemoryCache
来提高性能。我们使用
MemoryCache
的主要原因是因为我们需要在每个页面请求上执行一个强烈的查询。由于存在客户端回调,我们在每个页面请求上执行此查询x3次(在最坏的情况下)。我想知道如果EF 6已经使用了缓存机制,我们是否仍然需要使用
MemoryCache
机制。值得一提的是,我们没有使用任何特殊的缓存功能或缓存依赖项。只是一个简单的
MemoryCache
带有超时。MemoryCache
来提高性能。MemoryCache
的主要原因是因为我们需要在每个页面请求上执行一个强烈的查询。由于存在客户端回调,我们在每个页面请求上执行此查询x3次(在最坏的情况下)。MemoryCache
机制。MemoryCache
带有超时。You should not reuse EF context for more that one logical operation, because EF context represents unit of work, and so should be used according to this pattern. Also, even if you for some reason reuse context in multiple operations - you absolutely cannot do that in multi-threaded environment, like web server application.
It does not prevent you from making multiple queries for the same data to your database, for example:
var entity1 = ctx.Entities.Where(c => c.Id == 1).First();
var entity2 = ctx.Entities.Where(c => c.Id == 1).First();
This will still execute two queries to your database, despite the fact that query is the same and returns the same entity. So nothing is really "cached" in usual sense here. Note however, that both queries will return the same entity, even if database row has been changed between two queries. That is what is meant by EF context "caching". It will execute database query two times, but second time, while evaluating the result, it will notice that there is already entity with the same key attached to the context. So it will return this existing ("cached") entity instead, and will ignore new values (if any) returned by the second query. That behaviour is additional reason to not reuse the context between multiple operations (though you should not do it anyway).
如果您想减轻数据库的负担 - 您需要使用适合您需求的二级缓存(从简单的InMemoryCache到缓存EF提供程序再到分布式memcached实例)。
EF只实现了所谓的实体一级缓存,它存储了在上下文生命周期内检索过的实体,因此当您第二次请求该实体时,它会从上下文返回该实体。您需要的是第二级缓存,但EF没有实现这些功能。例如,NCache实现了一个出色的缓存架构和一个开箱即用的EF第二级缓存提供程序。但它不在其开源版本中。
context.Database.Log = Console.WriteLine
),然后执行相同的查询两次,你会看到执行了两个数据库查询。 - Evk