Is this the best way to use a Join for an OrderBy?

IQueryable<FieldDefinition> qFieldDefinition = from fieldDefinition in Query.All<FieldDefinition>()
                                                                   .Prefetch(item => item.Z_FieldGroup).AsQueryable()
                                                                   orderby fieldDefinition.Z_Name, fieldDefinition.Z_FieldGroup.Z_Name
                                                                   select fieldDefinition;

If I remove the .Prefetch() part I get an exception:

Unable to translate 'Query.All().OrderBy(fieldDefinition => fieldDefinition.Z_Name).ThenBy(fieldDefinition => fieldDefinition.Z_FieldGroup.Z_Name)' expression. See inner exception for details.^

Inner Exception:

Unable to cast object of type 'Xtensive.Storage.Rse.Providers.Compilable.JoinProvider' to type 'Xtensive.Storage.Rse.Providers.Compilable.SortProvider'.

Regards Paul Sinnema Diartis AG

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Jul 05 '10 at 13:40

Paul%20Sinnema's gravatar image

Paul Sinnema

One Answer:

You can't use AsQueryable method this way: it just wraps underlying IEnumerable to IQueryable by attaching the IQueryable infrastructure to it. When you extend such queryable further and execute it, the provider attached to it will simply compile its expression with Reflection.Emit, but original root there will be enumerable you converted to queryable, i.e. finally it's nearly the same as dealing with enumerable, all the difference is that you (technically) can use an expression describing it.

DO4 can't compile a query with IEnumerable.AsQueryable method call: it doesn't have any info about sequence you passed to AsQueryable method, so even if we'd implement best possible support for this, DO would be able only to pass this sequence to server as local collection. So in your case it would work as:

  • execute Query.All<fielddefinition>().Prefetch(...)

  • send the sequence as local collection to server (via temporary table)

  • execute a server-side query involving it: tmpCollection.OrderBy(...).Select(...).

That's it. But this doesn't work - as I just shown, there is no reason to support AsQueryable calls. We provide more explicit API allowing to "push" the collection to server - there is Query.Store<t>(IEnumerable<t> sequence) method. Details: http://goo.gl/SRln

answered Jul 06 '10 at 08:57

Alex%20Yakunin's gravatar image

Alex Yakunin

Concerning your case: all you need is to move .Prefetch(...) calls to the tail of call chain. Since they turn queryable into enumerable, they must be in the end.

(Jul 06 '10 at 08:57) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview


Once you sign in you will be able to subscribe for any updates here



Asked: Jul 05 '10 at 13:40

Seen: 3,152 times

Last updated: Jul 05 '10 at 13:40

powered by OSQA