XPO Lightweight Associations
EDIT: Added a little extra to the Workaround scenario by saying we want to open a "detail" object and have a grid with the associated records in it, displaying a FK from another association within that object. such as PurchaseOrder > Agreement > Sale, whereby you want to open the PurchaseOrder and list all associated Agreements displaying the Sale.Id in the grid, but without downloading the Sale Object.
One issue I still have with XPO is when using Associations you end up with alot of extra data retrieved from your database that you may not even need to access.
In some scenarios all I need access to is the Foreign Key and not all the other data of that object.
Scenario
Say you have an application that lists and edits Blog posts, when the application starts you obtain a User object containing the Id, Fullname and all the other data and within your Blog object you have a CreatedBy property which is associated with the User object. This will store a Integer (or GUID) in the Blog table as the FK.
By default when you get a XPCollection of Blogs you would also have joins for the CreatedBy to grab all the User objects as well. We can stop this from happening by using the DelayedProperty pattern.
Problem
When users try to edit the blog, we want to check if the current user logged in created this blog record. If you do MyBlogObject.CreatedBy.Id = LoggedInUserId you will have to download the entire User Object to do this. Which is crazy as all we needed was the FK which is stored in the Blog record already.
Workaround?
Now I did some more research into DelayedProperties, we can do some funky Reflection calls and obtain the “Key” from the XPDelayedProperty class. Unfortunately as most of this members are sealed/internal you have to use Reflection to access them.
This is what I ended up with
So what does that do exactly?
- mi stores the MemberInfo for the “delayed” property we want to obtain the key from
- GetCustomPropertyValue is a MethodInfo of a internal method that allows to get the value from the CustomProperty store of the Persistent object that XPO uses
- Invoke the GetCustomPropertyValue method using parsing mi (MemberInfo) of our delayed property which if the Property has been marked with DelayedAttribute should return a XPDelayedProperty object
- We then check if the XPDelayedProperty object has been loaded in other words, has XPO already hit the database for the object, if so we can return the Id straight from this object, otherwise we invoke to obtain the value of “_value” which is what XPO uses to store the FK BEFORE it hits the DB for the actual record.
Example use of this in a object
In this example we have an object (lets call it an Agreement) that has an Association to a Sale. Within the Agreement we also have an Association with a PurchaseOrder record. Now say I open the PurchaseOrder in a "detail" window, and have an editable grid setup with the list of Associated Agreements and in that list I want to show what SaleId they relate to (as my users understand and deal with Sale ID’s all the time), I can in this case have a column showing SaleId instead of Sale.Id. This reduces the amount of data returned from the database by over 200%.
So is this great? no unfortunately it only half solves the problem
Whats the problem now?
Unfortunately when XPO grabs the Blog record object, as the CreatedBy property is marked as Delayed, XPO doesn’t obtain the FK. So if we use the GetRawId method you will still be hitting the DB to obtain the FK value (at least this is still smaller than having to obtain the entire User record).
Ultimately we need XPO to ascertain if a Delayed property is an association, if it is an association to grab the FK in the first hit to the database in preparation to downloading the related object.
What would be better yet, is for XPO to have a built in way to obtain the FK of an association instead of the associated object at all times.
What to do?
This problem has affected me since last year (when the blog posts stopped) and it took a while for me to get around to getting back to publishing my findings and also asking DX for official support for this scenario. So with that in mind, I present this blog and this suggestion
http://www.devexpress.com/Support/Center/p/S137254.aspx
Cheers
Latest Comments
- Simple Collection to...
Hey Norman, Keep in mind that Baritem ar... More... - Simple Collection to...
Great many thanks - this said, I'm looki... More... - Simple Collection to...
I just checked my class here and it stil... More... - Simple Collection to...
I'm using Winform DevExpress Library - a... More... - XPO ObjectLayer Tuto...
Cheers Glen, I have held off continuing ... More...






Comments
community.devexpress.com/forums/p/100924/343968.aspx#343968
RSS feed for comments to this post.