Ticket Q446111
Visible to All Users

Pre fetch collections using XPQuery

created 12 years ago

Althought documentation for the Session.Fetch method is very brief I got to understand it works for XPCollection only. Since we were advised by DevExpress to migrate our querying to use Linq to XPO with XPQuery I'm having a hard time figuring out how to do that.
The reason I need to do that is, of course, performance. I've got an aggergate root and I need to return data for a RESTful service which will be "denormalized". I really need something like nHibernate have:

C#
session.Query<User>() .Fetch(e => e.Employer) .FetchMany(u => u.Orders) .ThenFetchMany(o => o.OrderItems

This way XPO woudln't emmit countless queries for each separate referenced property and could use a simple join to get all data in one round-trip.

(unless I'm mistaken I beleive referenced objects are lazily loaded, right?)
Here is what the context I'm trying to use it:

C#
public class Root : XPObject { public Root(Session s) : base(s) { } public string Name { get; set; } public Child FirstChild { get; set; } public Employer Employer { get; set; } } public class Child : XPObject { public Child(Session s) : base(s) { } public string Name { get; set; } } public class Employer: XPObject { public Employer(Session s) : base(s) { } public string Name { get; set; } } public class RootDto { public int rootId { get; set; } public string rootName { get; set; } public int firstChildId { get; set; } public string firstChildName { get; set; } public int employerId { get; set; } public string employerName { get; set; } } public class RootsController : ApiController { public IEnumerable<RootDto> GetAllRoots() { var query = from r in new XPQuery<Root>(new Session()) orderby r.Employer.Name select new RootDto { rootId = r.Oid, rootName = r.Name, employerId = r.Employer.Oid, employerName = r.Employer.Name, firstChildId = r.FirstChild.Oid, firstChildName = r.FirstChild.Name, }; return query; } }

I want XPO to issue a single SQL statement to the server, which it could do only if I could set prefetch to Employer and Child. Something like this:

C#
public class RootsController : ApiController { public IEnumerable<RootDto> GetAllRoots() { var query = from r in new XPQuery<Root>(new Session()).Fetch("FirstChild", "Employer") orderby r.Employer.Name select new RootDto { rootId = r.Oid, rootName = r.Name, employerId = r.Employer.Oid, employerName = r.Employer.Name, firstChildId = r.FirstChild.Oid, firstChildName = r.FirstChild.Name, }; return query; } }

Or Fetch(c => new { c.FirstChild, c.Employer } if you like lambdas a lot…
Is there any way I could optmize this call without actually resorting to use SQL instead of XPO to retrive this data from the server? Am I wrong in assuming that XPO is lazy loading Employer and Child, which will require a round-trip to the server for each unloaded Child or Employer it finds when enumerating the results of this Web Api method?

Answers

created 12 years ago (modified 12 years ago)

Hello Felipe,
It appears that the ExplicitLoadingAttribute should meet your needs. You will be able to load all associated objects in a single query with this attribute. Hope you will find this solution helpful.

    Show previous comments (6)

      Thanks so much Felipe for your detailed info (thats the way!) : I agree with your comment about Devexpress having greate ideas,features, and products but very BAD documentation, and the know-how - does not exist. I been very worry about performance using XPO WCF, Just to extend my frustation a bit more… the samples they put out (very unreal) . for a short sample: TO LEARN about preFecth . this is their definition "Populates the specified collections and delayed properties. " and it is correct BUT does it…(what about a collection that also has a collection?) what about references on how to tune it on the real world as Web develop. Our company is moving away from RIA were we hit some problems (not worth to mention!), and thinking that XPO will help us to develop faster with a better code\easy to understand (of course it will help many developers were the mini-samples are exactly what they are doing).
      I learn more from your comments and this post than any where else. thanks
      Maybe you can start a blog of your findings 'cause we are ready to test XPO WCF performance and you are way ahead
      of us. (where can we read about developing XPO WCF for the real web world; bet you that many people are asking the same thing that you describe here - is it this way better, shall I put this attribute here - how to tune to improve performance)
      one thing I really miss from the RIA is the amount of info they have, the real apps trainning videos, books ,StackOverflow. Great documentation and there is so much to say… (you may delete this two lines if it is out of line. thanks)
      That's it… thanks Felipe ,very good info.
      you can skip readng the rest of this comment.
      Devexp: the support has greate responding time , but sometimes they dont have enough samples that they have to point you to either complicated samples or very short. Happened to me (e.g we would like to use the DxScheduler for Silverlight and all the help I got is a reference to a 5 or 6 year old code, nothing related to Silverlight, when I replied to it, I was told in summary that's it.

        Hi Ruamnz, I'm very happy to have been able to help someone outthere. I've taken SO MUCH from the entire development community that any little bit I give back is not near enough! :-) And I'm passionate about DevExpress since the time from the Quantum Grid for Delphi! So I take me dear time to comment on their technology and I do bother them a LOT when I think something is wrong. At one time I've ranted so much on the forums that I even got a call from them on my phone (and I do live in Rio de Janeiro, so it was an international call for them!) explaining that they would be introducing a Lightweight rendering mode for most of their controls (all was rendered with tables, without semantic HTML, and I thought it was so, so wrong… and know it is right, so you can be sure they listen to us, they just don't listen as much as I would like, and like any dev team, they got to deliver! They have deadlines! They have to prioritize! They are just like us! Just a little more famous…)
        Let's get back to the important matter: ORMs! They are not a magic tricky. Unless we're talking about "No-SQL" databases (which are not ORM, as it's not relational, but are somewhat alike since they bridge the gap from objects to persistence…) we have to take a LOT of considerations when designing our classes and think a LOT about how the ORM will end-up persisting them.
        I believe that experience with multiple ORMs is really the crucial point in making you aware of what works and what doesn't. In this aspect I strongly advice everyone to try out nHibernate 3+ as a "mental exercise". You may (and should) stick with XPO because it really integrates more tightly with DevExpres offerings, and it will be very hard for any other ORM to beat the XpoDataSource in server mode and ASPxGridView working in tandem :-) But the lessons learned by exercising over nHibernate, and mostly reading Ayende's posts on the subject, will make you a better XPOer!!! Because most of the lessons translate directly to some or other technology inside XPO. And nHibernate (and Hibernate) documentation is vast, and community resources staggering.
        And you'll have background to challenge some assumptions made by the XPO team, or to see where the documentation is misleading.
        And the most important thing is to use a SQL PROFILER to see how XPO (and any ORM) is behaving or misbehaving!
        Unfortunately I never understood how to use the XPO Profiler. I've used the amazing NHibernate Profiler from the very same Ayende and learned a LOT about it, so I was so hopeful about XPO Profiler, but it turned out to be useless for me. So much noise and very little important information. I believe only the builders of XPO know how to use it! It is not uncommon for a single page load of my production site to generate thousands of entries, and the interface is really hard to get! I just can't see the issued queries!!!
        But nHibernate also have its problems, for an example here is one question which no one was able to answer in Stack Overflow: http://stackoverflow.com/questions/11150260/nhibernate-emitting-extraneous-update-statements-regardless-of-proper-inverse-f
        (to summarize it: something was emitting extra SQL statements, but it shouldn't. Playing around with the mapping resolved it but it still seems unnecessary in the first place: LESSON LEARNED: The profiler is your guide! Always use the profiler!)
        I've got a blog, but so little time to write anything on it… It can be reached here: http://feliperochamachado.com.br/blog/ I'm planning a series of articles on XPO, but I don't know when I'll be able to write them!
        Sorry for this futile, useless, long and boring post! And thank you for the appreciation for my previous useful ones…

          Felipe: (lost track of this article)
          with all the amount of info you are sharing ,nothing is boring Felipe, I agree again, they must have short time frames to maintain such a greate product. (nonsense documentation). In a bottom line greate product the worst doc.
          greate support - worst real life samples - all the rest was said. I will check your blog for more help. stay well.
          Ppeople don't take this personally it happens to all of us! and we know how your feel and still doing a greate job.

          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.