This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I'm just tweaking performance on a proof-of-concept web application using LightSpeed. I'm storing users and roles in the DB to enable role-based access - a fairly typical set-up with Users and Roles tables joined via an intermediary UserRoles table (one-to-many on both sides). In LightSpeed I've set up a ThroughAssociation from Users to Roles via UserRoles and set the collections and entity holders on both sides to be eager loaded, and turned on caching for all three entities. I have an 'IsInRole' method along these lines: return (from r in CurrentUser.Roles where r.RoleName == role select r).Count() > 0; My issue is this: if the CurrentUser entity has been loaded from the database this works, but if CurrentUser has been retrieved from cache the Roles ThroughAssociation is always empty. Is this expected behaviour? Any suggestions for a workaround? |
|
|
Looking at the code again I realise that since the generated EntityCollection properties are read-only they can't possibly be stored in cache. I can get the IsInRole code to work by calling something like CurrentUser.UserRoles.Count - this forces the entity collections to populate and the code works. However, this is a DB hit which I'm trying to avoid. As a hack around this I've added a string[] RoleNames property to my User partial class in the hope that this array would be cached. I've tried populating it in the AfterLoad override but looking at a trace log it seems this event is raised after the entity is cached. Is there any way to carry out custom logic on public properties in between being fetched from the database and being cached?
|
|
|
Hi rweaver :) When an entity is cached, the values of the persisted fields are copied to one side and stored in the cache. These are then set back against a fresh entity when fetching from the cache, so yes, the behavior your are seeing is expected. A possible workaround here would be to have the ThroughAssociation initialized after a lazy load of related collection, and then refresh both the collection and the ThroughAssociation after retrieving it from the cache and re-attaching it to a current unit of work.
Jeremy |
|
|
Not currently, but we could look at allowing Transient fields to be optionally marked as cached and then persisted/revived through the caching infrastructure to support this. Would be interested in your thoughts on this approach and if this would be what you are looking for.
Jeremy |
|
|
That would be great, I can think of one or two other uses for this as well. The API could just be an attribute to decorate the transient property to be cached. You'd either need a new event (BeforeCache) or move the caching process until after AfterLoad so that these could be populated - I'd vote for the latter but I guess that's dependant on internal architecture. Richard |
|
|
Thanks for the feedback Richard, Can you elaborate on your thoughts around the eventing? If we were to cache Transients, would you not just want them restored from the cached copy?
Jeremy |
|
|
Looking at the tracing it seems that an object is cached immediately after being loaded, before the AfterLoad method fires:
BeforeLoad()
...Load...
...Cache...
AfterLoad()
For my Transient to be useful I need to populate it in between being loaded and being cached.
Presumably there's a way to update the cache in AfterLoad, but that doesn't seem very efficient.
If I'm missing something here, please let me know!
Richard
|
|