Perhaps I am misunderstanding the caching that DbContext
and DbSet
does but I was under the impression that there was some caching that would go on
EF6 doesn't do results caching ootb. In order to cache results, you need to use a second level cache. See this promising project on CodePlex:
Second Level Caching for EF 6.1
Keep in mind that if data changes on the db, you won't immediately know about it. Sometimes this is important depending upon the project. ;)
Sometimes I use my extension method:
using System.Linq;
using System.Linq.Expressions;
namespace System.Data.Entity
{
public static class DbSetExtensions
{
public static TEntity FirstOrDefaultCache<TEntity>(this DbSet<TEntity> queryable, Expression<Func<TEntity, bool>> condition)
where TEntity : class
{
return queryable
.Local.FirstOrDefault(condition.Compile()) // find in local cache
?? queryable.FirstOrDefault(condition); // if local cache returns null check the db
}
}
}
Usage:
db.Invoices.FirstOrDefaultCache(x => x.CustomerName == "Some name");
You can replace FirstOrDefault with SingleOrDetfault also.
It is very clear on MSDN. Please note what is find
[https://docs.microsoft.com/en-us/ef/ef6/querying/][1]
using (var context = new BloggingContext())
{
// Will hit the database
var blog = context.Blogs.Find(3);
// Will return the same instance without hitting the database
var blogAgain = context.Blogs.Find(3);
context.Blogs.Add(new Blog { Id = -1 });
// Will find the new blog even though it does not exist in the database
var newBlog = context.Blogs.Find(-1);
// Will find a User which has a string primary key
var user = context.Users.Find("johndoe1987");
}
What @emcas88 is trying to say is that EF will only check the cache when you use the .Find
method on DbSet
.
Using .Single
, .First
, .Where
, etc will not cache the results unless you are using second-level caching.
This is because the implementation of the extensor methods, use the Find method of the context
contextName.YourTableName.Find()
to verify first the cache. Hope it helps.
Take a look at EF Docs, you will find answer there:
Note that DbSet and IDbSet always create queries against the database and will always involve a round trip to the database even if the entities returned already exist in the context. A query is executed against the database when:
- It is enumerated by a foreach (C#) or For Each (Visual Basic) statement.
- It is enumerated by a collection operation such as
ToArray
,ToDictionary
, orToList
.- LINQ operators such as
First
orAny
are specified in the outermost part of the query.- The following methods are called: the
Load
extension method on aDbSet
,DbEntityEntry.Reload
, andDatabase.ExecuteSqlCommand
.