Yes you can and it does make sense to cache a frequently used object if you are fetching it based on a property that is not the primary key.
My site has a Person class which represents a specific user on the site. On any given web request I need to fetch the current logged-in user object several times to access various configuration settings and properties that are specific to the current user. Rather than hitting the database every time, I store the current user in HttpContext.Items[] and I have a static method that checks if the Items cache contains the current user. If it does, return it, if it doesn't get it from the database and add it to the cache so its available next time:
public static Person CurrentUser
{
get
{
if(!IsAuthenticated) return null;
Person person = (Person) HttpContext.Current.Items[HttpContext.Current.User.Identity.Name];
if(person != null) return person;
IPersonDao personDao = new PersonDao();
person = personDao.getByUsernameEmail(HttpContext.Current.User.Identity.Name);
if(person==null)
{
FormsAuthentication.SignOut();
HttpContext.Current.Response.Redirect("/");
}
HttpContext.Current.Items[HttpContext.Current.User.Identity.Name] = person;
return person;
}
}
I also store my NHibernate session object in HttpContext.Items so the session and the cached object will be garbage collected at the same time at the end of the HttpRequest, what you don't want is for the object to survive past the lifetime of the session, otherwise a new session may start and NHibernate will barf with a NHibernate.NonUniqueObjectException because the object is bound to another session.
Its worth pointing out that the NHibernate's 1st level cache keeps all objects accessed by the session cached by ID. If I was calling session.get(id) there is no need to cache as NHibernate's 1st level cache maintains objects by their id. But in the above case where I am fetching the person object by the User.Identity.Name the 1st level cache doesn't work as the user's username is not the primary key of the object.
More info on HttpContext.Items http://aspnet.4guysfromrolla.com/articles/060904-1.aspx
DO NOT use HttpContext.Cache, which for some reason lasts beyond the Http Request.