LINQ, skip and accept the order

I did some tests with Take and Skip and I found that:

var objects = (from c in GetObjects() orderby c.Name select c); var skipTake = objects.Skip(5).Take(10).ToList(); var takeSkip = objects.Take(10).Skip(5).ToList(); 

GetObjects () returns the IQueryable generated by NHibernate (3.3.3GA using SQL Server 2008 R2 DB).
skipTake and takeSkip contain the exact same sequence of 10 objects.
But if I write

 var objects = (from c in GetObjects() orderby c.Name select c).ToList(); var skipTake = objects.Skip(5).Take(10).ToList(); var takeSkip = objects.Take(10).Skip(5).ToList(); 

skipTake contains the same sequence as the previous example, while takeSkip contains a different sequence of 5 objects.

Take & Skip calls reorder when they apply to IQueryable?
I would like to get some idea about this.

Thanks in advance.

+5
source share
3 answers

This seems to be due to an error in certain versions of nhibernate:

http://sourceforge.net/p/nhibernate/news/2013/03/nhiberate-333ga-released/

BEWARE: in versions prior to 3.3.3.CR1, the processing of the LINQ Take () method was spoiled - no matter where the Take () request was placed, it was always applied as if it were placed at the end. 3.3.3 fixes this, so Take () now correctly follows .Net semantics. That is, in 3.3.3, the following queries can now give different results:

 session.Query<Foo>.OrderBy(...).Take(5).Where(...); session.Query<Foo>.Where(...).OrderBy(...).Take(5); 

Starting with 3.3.3, the first query will generate a subquery to correctly apply the line limit to the where clause.

+2
source

Do Take and Skip calls reorder when they are applied on IQueryable? I would like to get some idea about this.

I think that the answer to this question should be formulated as follows:

skipTake is the result of skipping the first 5 IQueriable elements and the next 10. So, for example, in the list of ordered numbers from 1 to 20 skipTake will have 6 → 15 subscriptions.

takeSkip is the result of taking the first 10 elements of IQueriable, and then skipping the first 5 elements of the subexpression (!). Therefore, using the list from the previous example, takeSkip will have 6 → 10 subscriptions.

In the first part of your observation (where skipTake and takeSkip contain the same 10 elements), this should be considered as incorrect behavior (or possibly even an error) in the implementation of NHibernate.

0
source

First, I find that the @ https://stackoverflow.com/users/2617732/rdans answer is not relevant to your specific example, since you are not applying the where clause after Take .

However, in Example A, both skipTake and takeSkip should generate the same SQL, where it will select the first 10 rows after the 5th row (for a SQL server, for example, with ROW_NUMBER OVER(...) ).

It seems to me that in example B you are trying to take Take and Skip not on IQuerable , but on System.Collections.Generic.List<> (which, of course, is not a territory of NHibernate).

In this case, objects has N elements.

skipTake will be first Skip 10 elements and from the resulting enumeration (which lists over N-10 elements), then Take first 5 elements.

Given that the results are already ordered, the result of skipTake ToList should be the same as in Example A.

takeSkip on the other hand, the first Take 10 elements and from the resulting enumeration (which lists 10 elements) Skip first 5.

So what

0
source

All Articles