Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does EF caches entities between different instances of DbContext?

Does creating DbContext per query in Asp.net make EF only read the data from its cache, or does it query DB for the whole sets every time? I know about metadata caching per AppDomain, but what about just the data?

Context: data acquisition and visualisation application with MVC4 + Web API frontend, wouldn't call that "high volume", but lots of queries return the same sets of data in some shorter time frame.

like image 932
mrówa Avatar asked Jun 11 '13 11:06

mrówa


People also ask

Is DbContext cached?

The DbContext provides a first-level cache for objects that it is asked to retrieve from the data store. Subsequent requests for the same object will return the cached object instead of executing another database request.

Does Entity Framework cache data?

Entity Framework has the following forms of caching built-in: Object caching – the ObjectStateManager built into an ObjectContext instance keeps track in memory of the objects that have been retrieved using that instance. This is also known as first-level cache.

Does EF core cache data by default?

The Cache: The memory cache is used by default. The Cache Key: The cache key is created by combining a cache prefix, all cache tags and the query expression. The Query Materialized: The query is materialized by either using "ToList()" method or "Execute()" method for query deferred.

Does EF core cache queries?

It's important to clarify that EF Core already automatically compiles and caches your queries using a hashed representation of the query expression. When your code needs to reuse a previously executed query, EF Core uses the hash to lookup and return the compiled query from the cache.


1 Answers

Entity Framework doesn't have a data cache per AppDomain, only a cache per context instance.

If you create a new context per request or query you start with an empty cache and EF will fetch the data from the database.

Moreover, the term "cache per context instance" can be misleading as it doesn't mean that EF won't run queries to the database if the entities are already loaded in the context cache. The way how this cache works and how you can leverage it (or not) is the following:

  • Every LINQ-to-Entities query on a DbSet<T> or generally on an IQueryable<T> will run a database query, no matter if the entities already exist in the context or not. But if an entity with the same key as a queried entity already exists in the context EF will throw the result of that query away and return the cached entity instance back to the caller.

    It does this check if the entity with the same key exists after it has run the query. (For complex queries - for example queries that contain an Include - it can't do this check before because it cannot know which entities and key values will be returned.)

    That's the default behaviour (MergeOption is AppendOnly). You can change this behaviour to OverwriteChanges and other options, I believe, but none of them will avoid that LINQ queries always issue database queries.

  • For querying an entity just by its key you can use GetObjectByKey or Find (with DbContext) which will check first if the entity with that key is already cached in the context and then return this cached object. If not it will run a database query to load it.

  • You can query EF's ChangeTracker, it's especially well supported with DbContext where you have access to the context cache via the DbSet<T>.Local collection.

    The problem here is that there is no logic to query the database automatically if a query on Local does not return a result. You have to write this logic manually. The even bigger problem is that a query on Local is LINQ-to-Objects and not LINQ-to-Entities (Local doesn't implement IQueryable<T>, only IEnumerable<T>), so you often have to rewrite your queries to act on Local - for example you can't use Include here, your can't use any EntityFunctions, you will get different behaviour for string comparisons regarding case sensitivity, etc., etc.

like image 116
Slauma Avatar answered Nov 01 '22 00:11

Slauma