25

Say I have a table or 2 that contains data that will never or rarely change, is there any point of trying to cache those data? Or will the EF context cache that data for me when I load them the first time? I was thinking of loading all the data from those tables and use a static list or something to keep that data in memory and query the in memory data instead of the tables whenever I need the data within the same context. Those tables I speak of contains typically a few hundred rows of data.

0

3 Answers 3

22

The EF context will cache "per instance". That is, each instance of the DbContext keeps it's own independent cache of objects. You can store the resulting list of objects in a static list and query it all you like without returning to the database. To be safe, make sure you abandon the DbContext after you execute the query.

var dbContext = new YourDbContext();
StaticData.CachedListOfThings = dbContext.ListOfThings.ToList();

You can later use LINQ to query the static list.

var widgets = StaticData.CachedListOfThing.Where(thing => thing.Widget == "Foo");

The query executes the in-memory collection, not the database.

Sign up to request clarification or add additional context in comments.

3 Comments

Can i add list of results directly in Cache collection? I mean HttpRuntime.Cache["MyKey"] = context.ListOfThings.ToList()
@ed-chapel I don't why this is a good idea, there are more cases where the data that we want to cache changes rarely (but it still changes). Using your suggestion won't help when a change occurs, or am I missing something?
@K-SaMa You are right, this does nothing to refresh the data. This solution merely prevents, as the OP asked, how to prevent repetitive calls. Detecting and updating the cache are different harder problems, not asked here.
12

You can check EF caching provider but be aware that caching in this way is performed strictly on query basis - so you must use the same query all the time to get cached data. If you use another query it will first be executed to be considered as cached and then you use it again to hit the cache. If you want to avoid this and cache data with ability to run any query on cached collection you must roll on your own solution (simply load data to list and keep it somewhere). When you load entities to cached list make sure that you turn off proxy creation (lazy loading and change tracking).

Caching per context instance really works but using context itself as a cache is pretty bad choice - in most scenarios I would call it EF anti-pattern. Use context as unit of work = do not reuse context for multiple logical operations.

Comments

1

you'll have to roll your own for any ef4 linq queries, as they are always resolved to sql, and thus will always hit the db. a simple cache for your couple tables probably wouldn't be hard to write.

if you're going to be querying by id though, you can use the ObjectContext.GetObjectByKey method, and it will look in the object cache before querying the db.

7 Comments

Careful, "linq is always resolved to sql" is very untrue. LinqToObjects is one of several providers that has nothing to do with SQL or a database in general.
It depends. If the user includes a ToArray() or ToList() or otherwise forces the query to execute against the database, then subsequent expressions are frequently not LinqToEF. Your statement is too absolute with "always".
@ed, it is absolute. they aren't sometimes resolved to sql, they always are. if someone evaluates the query, they have to start a new one, and then its not the same query... this isn't really a debate here, its just simple facts. from msdn.microsoft.com/en-us/library/bb896241.aspx "When you query a conceptual model, the Entity Framework transforms the LINQ to Entities and Entity SQL query based on the conceptual model into an equivalent query against the data source." seems pretty absolute to me.
@ed, i think you're missing the core point here. of course when you query a list<string> it doesn't hit the database.there is no databse to hit. its when you query an object context.
Fair enough. It appears as though we were speaking past one another. Should anyone read this far, do take Nathan's warning about avoiding the database.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.