Entity Framework does not have a data cache for AppDomain, but only a cache for each instance of the context.
If you create a new context for each request or request, you start with an empty cache, and EF will retrieve data from the database.
In addition, the term "cache for each instance of the context" can be misleading, as this does not mean that EF will not start querying the database if the entities are already loaded into the context cache. The way this cache works and how to use it (or not) is as follows:
Each LINQ-to-Entities DbSet<T> on DbSet<T> or even on IQueryable<T> will trigger a database query, regardless of whether entities exist in the context or not, But if the object with the same key as the requested object, already exists in context, EF will throw the result of this request and return the instance of the cached object back to the caller.
This checks if an entity exists with the same key after it has fulfilled the request. (For complex queries — for example, queries containing Include — he cannot perform this check earlier because he cannot know which objects and key values will be returned.)
This is the default behavior ( MergeOption equals AppendOnly ). In my opinion, you can change this behavior to OverwriteChanges and other parameters, but none of them will avoid the fact that LINQ queries always cause database queries.
To query an object by its key, you can use GetObjectByKey or Find (with DbContext ), which first checks if an object with this key is already cached in context, and then returns this cached object. If not, it will run a database query to load it.
You can request EF ChangeTracker, which is especially well supported with DbContext , where you have access to the context cache through the DbSet<T>.Local .
The problem is that there is no logic to automatically query the database if the query on Local does not return a result. You must write this logic manually. An even bigger problem is that the query for Local is LINQ-to-Objects, not LINQ-to-Entities ( Local does not implement IQueryable<T> , only IEnumerable<T> )), so you often have to rewrite your queries to Local - for example, you cannot use Include here, you cannot use any EntityFunctions , you will get different behavior to compare strings in relation to case sensitivity, etc. etc.
Slauma
source share