Search code examples
asp.net.netnhibernatequeryover

NHibernate QueryOver - Doing Fetches and OrderBy -> What Syntax to use?


All,

I have a query as such:

_AddOrderBy(sortOptions, query)
                .Fetch(x => x.ImageType).Eager
                .Fetch(x => x.User).Eager
                .Fetch(x => x.Partner).Eager
                .Inner.JoinAlias(x => x.Partner, () => p).Fetch(x => x.Company).Eager

                .Skip(startIndex)
                .Take(pageSize)
                .List<ImageRequest>();

In the above QueryOver I call _AddOrderBy() method which adds an order by clause. The challenge I face is how do I create an "order by" that references a property (ordering by "CompanyName") that lies within the following association path without conflicting with my Fetch()/Inner joins:

ImageRequest.Partner.Company.CompanyName

Inside my _AddOrderBy() I have this:

Partner p = null;
            Company comp = null;
            order = query.Inner.JoinAlias(x => x.Partner, () => p)
                .Inner.JoinAlias(x => x.Company, () => comp)
                .OrderBy(x => comp.CompanyName);

But this gives me a run time exception stating that I have duplicate key (referring to Partner) in the criteria. I can see that this is conflicting with my eager fetching. My questions is:

How do I add an "order by" so it works with my Fetching.


Solution

  • The beauty of using an Alias in QueryOver is that you don't have to use Fetch or JoinAlias in your _AddOrderBy() method again if the Join happens in the query already. You only need to declare the Alias with the same name.

    Therefore your _AddOrderBy() can just look like this:

    Partner p = null;
    Company comp = null;
    order = query
        .Inner.JoinAlias(x => p.Company, () => comp) // you can use p here if it was used in the query before
        .OrderBy(x => comp.CompanyName);
    

    The reason this works is this: If you put the whole code into one method it will obviously work. Splitting it into two methods still works, because Partner p is not a reference to an object in memory but an Alias that is simply translated into a string for the SQL query.