Another cache question

Posts   
 
    
tuppers
User
Posts: 16
Joined: 09-Feb-2009
# Posted on: 16-Jun-2009 17:54:52   

Hi,

Sorry to bring up the subject of caching again as there seems to be many threads and even an article written by Otis on the matter. But I have a problem with the way the uniquing cache has been implemented and hope someone may be able to suggest something I can do.

To set the scene here is an example that highlights the problem that is causing my application to run slowly:

  • I have an entity Person that has a property PersonType.
  • _PersonType _is a object with the properties _Description _and Grade.
  • _PersonType _is linked to _Person _via a foreign key in the database.
  • There are only 3 rows in my _PersonType _table

In my code I want to do something like:

foreach (Person aPerson in personCollection) { string text = aPerson.PersonType.Description; }

The problem occurs when _personCollection _starts getting larger, say 200 records, as each time I ask for the _PersonType _property it will hit the database generating 200+ SQL hits.

If there is a way of implementing a short lived cache (NHibernate refers to it as a level 1 cache) it would reduce my SQL hits from 200 to 3 (there are only three different types of Person) which is clearly a big saving.

At first glance it seemed a context would sort me out as this deals with uniquing but unfortunately although this ensures the you don’t re-instantiate the same object over and over again, it still hits the database to check the data is fresh.

This seems like an obvious requirement to me and one that has been overlooked in previous discussions. Am I missing something? Is there something I can do to stop my database being hammered?

Thanks

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 16-Jun-2009 18:16:45   

Hi Tuppers,

Absolutely you can do this. What you're looking for is called a Prefetch. A Prefetch allows you to retrieve many related Entities at once.

So, when you fetch your Person collection, you also want to fetch the PersonType. Please look in the manual for Prefetch Paths.

Hope this helps!

Ryan

PS. Context is quite different. Context does not prevent database hits. The purpose of the Context is to match Entities already in-memory with Entities being fetched from the database. This way - you can add additional Entities to your in-memory Entity Graph. Very helpful when Entities were not Prefetched together. In other words, when fetching from the database - the Context prevents separate Entity instances being created.

tuppers
User
Posts: 16
Joined: 09-Feb-2009
# Posted on: 17-Jun-2009 13:42:27   

Thanks Ryan, that is exactly what I needed smile