In particular, it is required to mention that when a delayed property is accessed in a set of objects (e.g., when it is bound to a grid column), a separate query for each record is generated by XPO. In addition, it will be helpful to suggest solutions to this issue - e.g., disabling the delayed loading feature for heavily used properties and pre-fetching delayed properties.
Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Not only Delayed loading. This N+1 query problem occurs with any persistent object which is not part of a collection. You normally want delayed loading for Collections (normally, not always, but almost always :-) but for simple referenced properties either they are really delayed loaded by some sort of proxy injection, or they should be loaded with a single round-trip to the server, in a single SQL statement with proper JOINS.
Currently XPO will issue a separate SQL statement to read each and every referenced property, take for example this:
public class Aggregator: XPObject
{
public Aggregator(Session s):base(s){}
public AggregatedObject1 Aggregated1;
public AggregatedObject2 Aggregated2;
public AggregatedObject3 Aggregated3;
public AggregatedObject4 Aggregated4;
}
public AggregatedObject1: XPObject
[…]
XPI will issue 5 SQL statements to fill Aggregator unless we mark it as Explicit Loaded.
In other words, ordinary properties aren't delayed but are "eager loaded" in a N+1 scenario! This is the worst case scenario. And I think the documentation don't touch on this issue enough.
I took me a few years of XPO development, plus experience with nHibernate, to actually grok the right way to do all of this, and I realized that DevExpress documentation actually directed me to the wrong way.
By judiciously applying DelayedLoading attribute and Explicit Loading I was able to make a simple page that issued next to 2000 queries, and took 10 seconds to display, to issue 4 queries (3 extraneous IMHO) and 200ms to display.
I do also think that XPO Linq provider should easy the pain of determining what to pre-fetch or delay loading, without requiring the attributes.
I do also believe that all simple, aggregated properties should be explicitly loaded by default unless they are delayed, as I can't see sense in issuing separate queries for all of them. If you know you'll fetch them, fetch them in a single round-trip!
Hi Felipe. Thanks a lot for this valuable comment. We will surely improve XPO documentation in this regard.
Documentation is good but we need Prefetchj for Linq and i mean ASAP. Right now i am stopping moving to XPO linq cause i cant use prefetch( and it is not good thing because i want to use linq- better code control )
Thank you for your feedback. This suggestion is related to the documentation of the delayed loading mechanism. If you wish to discuss an issue or suggest a new functionality, please create a separate ticket and describe the issue in greater detail.