Do we need external caching mechanism while EF 6 use caching out of the box?

asp.net c# caching entity-framework entity-framework-6

Question

I recently exposed to Entity Framework 6 caching mechanism. As we might figure from this article, it does it in First-Lever manner.

Our system uses EF 6 (code first) along with MemoryCache to improve performance.

The main reason we use MemoryCache is because we need to execute an intense query on every page request. We execute this query x3 times (in the worst case) on every page request since there are client call backs.

I wonder if we still need to use the MemoryCache mechanism if the EF 6 already use one.

It is worth saying that we don't use any special caching feature or cache dependencies. Just a simple MemoryCache with timeouts.

1
3
3/18/2017 11:13:04 AM

Accepted Answer

The fact that EF caches entities in context is in no way a replacement for "real" cache, for various reasons:

  1. 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.

  2. 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).

So if you want to reduce load on your database - you have to use second-level caching using whatever suits your needs (from simple InMemoryCache to caching EF provider to distributed memcached instance).

4
3/18/2017 11:52:56 AM

Popular Answer

EF only implements what is called first level cache for entities, It stores the entities which have been retrieved during the life time of a context so when you ask for that entity the second time it returns the entity from context. What you need is a second level cache but EF dosen't implants this features. NCache for example implements a wonderful caching architecture and a out of the box a second level cache provider for EF. Not in its open source version.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow