Does EF caches entities between different instances of DbContext?

99封情书 提交于 2019-12-05 05:24:39

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!