1

I'm refactoring my ASP.NET MVC 4 WebAPI project for performance optimization reasons. Within my controller code, I'm searching for entities in a context (DbContext, EF6). There are a few thousands of such entities, new ones are added on an hourly basis (i.e. "slowly"), they are rarely deleted (and I don't care if deleted entities are still found on the context's cache!) and are never modified.

After reading the answers to this question, to this one and a few more discussions, I'm still not sure it's a bad idea to use a single static DbContext for the purpose described above - a DbContext which never updates the database.

Performance-wise, I'm not worried about the instantiation cost, but rather about the uselessness of caching requested entities if the DbContext is created for each request. I'm also using a 2nd level caching, which makes the persistence of the context even more acute.

My questions are: 1. Regardless of the specific implementation, is a "static" DbContext a valid solution in my case? 2. If so, what would be the most appropriate way of implementing such a DbContext? 3. Should I periodically "flush" the context to clear the cache in order to prevent if from growing too big?

Community
  • 1
  • 1
ury
  • 1,050
  • 11
  • 22
  • If you look at the documentation of `Dictionary ` you see it makes a claim about beinh thread-safe when it is only read from. Those claims are missing from the `DbContext` documentation so we must assume it isn't thread-safe, even in read-only scenarios and even when you ensure the database is queried just once during a single-threaded initialization phase. – Steven Nov 02 '13 at 23:24

1 Answers1

0

DbContext caches entity instances when you get/query the data. It ensures different queries that return the same data map to the same entity (based on type and id). Otherwise, if you modify the same entity in different object instances, the context would not know which one has the correct data. Therefore a static DbContext would blow up over time until the process crashes.

DbContexts should be short lived. Request.Properties is a good place to save it in Web API (maps to HttpContext.Items in IIS).

Dmitry S.
  • 8,373
  • 2
  • 39
  • 49
  • As I said, entities are never modified anywhere, otherwise I wouldn't consider the static alternative. If you take this into consideration, and assume the DbContext cache can really boost performance (I'm looking for these entities ~1000 times each second), would you still consider a static DbContext a bad idea? – ury Nov 02 '13 at 18:18
  • The entities are still getting cached in the context if you only read/query the data because it has no idea if you are going to modify the data later. There is no way to disable it. – Dmitry S. Nov 02 '13 at 18:23
  • NHibernate has IStatelessSession for those scenarios but Entity Framework does not have anything similar. Edit: actually you can turn off tracking for queries using the ".AsNoTracking()" method. But make sure not to get entities by id. I still would not do it due to potential threading issues and some data can still be cached. – Dmitry S. Nov 02 '13 at 18:23
  • Dmitry, change tracking will obviously be disabled. Why do think I'd like to disable caching when all I want is to optimize caching by using it as much as I can? – ury Nov 02 '13 at 18:35
  • If the database can fit into memory without ballooning the worker process it may work. I would also research whether queries in the DB context are thread-safe or you may need to use locking. – Dmitry S. Nov 02 '13 at 20:24