Dan (DevExpress)
04.26.2004
1 Answer
XPO Session uses an internal object storage called Identity Map. This is not a cache actually.
Every time an object collection is reloaded, XPO queries the database for all objects that match the collection's Criteria. While processing the query result, XPO looks for an existing object instance by the object's key on the identity map.
* If an object is not found on the map, it is instantiated, and its properties are set based on the record data.
* If an object is found on the map, XPO compares the object's OptimisticLockField value against the OptimisticLockField value fetched from the data store. Different values indicate that the object has been changed, since it was loaded onto the map, and XPO updates all the object's properties with the record values fetched. If the OptimisticLockFieldvalue value hasn't been changed, the object's properties are not renewed with data store values.
If your persistent class doesn't support Optimistic Concurrency Control, XPO cannot detect whether a given object has been changed or not. In this case, the existing object is returned from the identity map, and its properties are not updated.
The objects are preserved on the identity map, until the application makes use of them. Once the application loses all references to an object, the .NET Garbage Collector can collect it, as XPO's Identity Map uses WeakReference for object references.
To refresh an object or discard changes made to its properties, call the object's Reload method.
You can force the Session to release all its objects by calling the Session.DropIdentityMap method. Please note that existing references to persistent objects become invalid after the DropIdentityMap method call. The objects must be reloaded then via the Session.GetObjectByKey, Session.FindObject, XPCollection.Reload, etc. methods.
XPCollection.Reload vs. XPBaseObject.Reload
XPBaseObject.Reload reloads an object's properties. A query is sent to the data store, and new values are assigned to the object's properties. Associated objects and collections are not reloaded. You may need to reload them by calling their Reload method.
XPCollection.Reload can be used to refresh a scope of objects. It also updates properties of changed objects. The changed objects are detected by their OptimisticLockField value, as explained above.
The Identity Map technique is very useful and effective, though it may have the effect of stale data in a multi-user application. For these applications we recommend that you split them into several logical blocks that use an independent XPO's Session or UnitOfWork in each block for data acquisition.
See Also:
Session Management and Caching
XPO Best Practices
How to log the SQL queries made by XPO
Optimistic Concurrency Control