My question how to retrieve an item by Id or by any other search criteria if we know that the item might be inside the cache.
Like in the method below GetAll get all the institutes and GetbyID get a particular institute by id. Now the question is that should GetbyID look into the Cache["INSTITUTES"] to just go to the database.
public List<Institute> GetAll()
{
SqlDataAccess dataAccess = new SqlDataAccess();
List = (List<Institute>) HttpRuntime.Cache.Get("INSTITUTES");
if (List == null || List.Count == 0)
{
List = dataAccess.GetInstitutes();
}
return List;
}
public Institute GetByID(int id)
{
// check the item in the cache
Institute institute = GetAll().Find(delegate(Institute i) { return i.InstituteID == id; });
Concat the the 'INSTITUTES' with the id, the result string can be the cache key.
Somethin like: INSTITUTES_1 indicating an institution in your database, so you are not hitting the database all the time.
Same method can apply to search criteria: SEARCH_MIT,
SEARCH_CALTECH. it's better you make the letter cases uniform so there won't be any confusion.
Or you can create a very light weight institute object for each institution, each with very few essential attributes, and then load them in the generic list, cache the list with the key
INSTITUTES, then you know that you always have all of them in cache, or none of them so you can go to db and load them in on trip.
Yes, this is my initial thought to get the Institutes by id. Something like INSTITUTES_ID format.
The problem now comes that when I add the institute then two of the keys will expire with is INSTITUTES (All Institutes) and INSTITUTES_ID format. How do I remove all the institutes keys when any new institute is added?
Offcourse I can do a StartsWith prefix INSTITUTES and remove all the objects in the cache. Is that the way to go?
Caching is meant to achieve high performance. Sounds there will be some loops involved in the logic. Maybe you can conside my second solution provided in my previous post. Just store the list object in the cache.
To retrieve any single institue is easy, first you check if Cache["INSTITUTES"] exists. If not, one trip to db, use a DataReader, while read each data row, you create a light institute object, and add it to the list. Once finish reading, close the connection,
add the list object to cache. Then you can retrieve the item by id easily from the list in your code, since the list got back from cache is the exact same object type of generic list, it's enumerable, so you can use foreach (institution in institutes) {...}
Whenever you have an institution to add, I'm not sure how frequent this would be, consider it's an institution, it may not be happening quite often on your db, maybe a batch load once a while could do it? It's up to you to decide if you want to do a refresh
load on every occasion of an instituion is being added or simply loop through the list inside cache, check for duplicate and then add.
There is a balance such that you don't want to make cache manipulation too complicated, meanwhile how fresh you want the data to be. Just keep in mind the ultimate goal of caching is performance, with resonable period of time that data is out of sync.
For the sake of simplicity for Krammer, I've made the example in generic List, if he wants to use the generic Dictionary, it's not a problem. What I believe he wanted to know is more on caching technique, not the actual type of data collection.
Well, thanks for all the answers. My question was that how can I distinguish between the Cached Item Globally and for user based. The real problem was building the key. But I guess I will append the ID of the item to the Key and then build the key.
Krammer
Member
54 Points
141 Posts
Caching Question!
Aug 04, 2007 02:55 AM|LINK
Hi,
My question how to retrieve an item by Id or by any other search criteria if we know that the item might be inside the cache.
Like in the method below GetAll get all the institutes and GetbyID get a particular institute by id. Now the question is that should GetbyID look into the Cache["INSTITUTES"] to just go to the database.
public List<Institute> GetAll()
{
SqlDataAccess dataAccess = new SqlDataAccess();
List = (List<Institute>) HttpRuntime.Cache.Get("INSTITUTES");
if (List == null || List.Count == 0)
{
List = dataAccess.GetInstitutes();
}
return List;
}
public Institute GetByID(int id)
{
// check the item in the cache
Institute institute = GetAll().Find(delegate(Institute i) { return i.InstituteID == id; });
return institute;
}
jackyang
Contributor
5816 Points
782 Posts
Re: Caching Question!
Aug 04, 2007 03:09 AM|LINK
Concat the the 'INSTITUTES' with the id, the result string can be the cache key.
Somethin like: INSTITUTES_1 indicating an institution in your database, so you are not hitting the database all the time.
Same method can apply to search criteria: SEARCH_MIT, SEARCH_CALTECH. it's better you make the letter cases uniform so there won't be any confusion.
Or you can create a very light weight institute object for each institution, each with very few essential attributes, and then load them in the generic list, cache the list with the key INSTITUTES, then you know that you always have all of them in cache, or none of them so you can go to db and load them in on trip.
.NET Developer
ASP.NET/jQuery Spell Checker
Krammer
Member
54 Points
141 Posts
Re: Caching Question!
Aug 04, 2007 03:17 AM|LINK
Thanks for the post.
Yes, this is my initial thought to get the Institutes by id. Something like INSTITUTES_ID format.
The problem now comes that when I add the institute then two of the keys will expire with is INSTITUTES (All Institutes) and INSTITUTES_ID format. How do I remove all the institutes keys when any new institute is added?
Offcourse I can do a StartsWith prefix INSTITUTES and remove all the objects in the cache. Is that the way to go?
jackyang
Contributor
5816 Points
782 Posts
Re: Caching Question!
Aug 04, 2007 03:34 AM|LINK
Caching is meant to achieve high performance. Sounds there will be some loops involved in the logic. Maybe you can conside my second solution provided in my previous post. Just store the list object in the cache.
To retrieve any single institue is easy, first you check if Cache["INSTITUTES"] exists. If not, one trip to db, use a DataReader, while read each data row, you create a light institute object, and add it to the list. Once finish reading, close the connection, add the list object to cache. Then you can retrieve the item by id easily from the list in your code, since the list got back from cache is the exact same object type of generic list, it's enumerable, so you can use foreach (institution in institutes) {...}
Whenever you have an institution to add, I'm not sure how frequent this would be, consider it's an institution, it may not be happening quite often on your db, maybe a batch load once a while could do it? It's up to you to decide if you want to do a refresh load on every occasion of an instituion is being added or simply loop through the list inside cache, check for duplicate and then add.
There is a balance such that you don't want to make cache manipulation too complicated, meanwhile how fresh you want the data to be. Just keep in mind the ultimate goal of caching is performance, with resonable period of time that data is out of sync.
.NET Developer
ASP.NET/jQuery Spell Checker
MatsL
Participant
1519 Points
259 Posts
Re: Caching Question!
Aug 06, 2007 01:00 PM|LINK
Why not using a dictionary that is indexed on Id?
Like Dictionary<int, Institute>.
Or maybe I'm missing the question...
http://www.softgear.se
http://mats.softgear.se
jackyang
Contributor
5816 Points
782 Posts
Re: Caching Question!
Aug 06, 2007 04:46 PM|LINK
For the sake of simplicity for Krammer, I've made the example in generic List, if he wants to use the generic Dictionary, it's not a problem. What I believe he wanted to know is more on caching technique, not the actual type of data collection.
.NET Developer
ASP.NET/jQuery Spell Checker
Krammer
Member
54 Points
141 Posts
Re: Caching Question!
Aug 06, 2007 08:35 PM|LINK
Well, thanks for all the answers. My question was that how can I distinguish between the Cached Item Globally and for user based. The real problem was building the key. But I guess I will append the ID of the item to the Key and then build the key.