kasperhj
kasperhj

Reputation: 10482

LINQ to SQL and the the order of Take() and Skip()

I am fiddling with LINQ to SQL and LINQ, and I have come across something which I cannot quite understand.

When I do this:

var a = Table.Select(s => s.Id).Take(5).Count();
var b = Table.Select(s => s.Id).Take(5).Skip(2).Count();
var c = Table.Select(s => s.Id).Skip(2).Take(5).Count();
Console.WriteLine("{0}, {1}, {2}", a, b, c);

I get

5, 5, 5

I would expect to get 5, 3, 5 (as is also the case if I try and simulate with a List)

var data = new List<int> {0, 1, 2, 3, 4, 5, 6};

var a = data.AsQueryable().Select(d=>d).Take(5);
var b = data.AsQueryable().Select(d=>d).Take(5).Skip(2);
var c = data.AsQueryable().Select(d=>d).Skip(2).Take(5);
Console.WriteLine("{0}, {1}, {2}", a, b, c);

5, 3, 5

What is going on?

Upvotes: 1

Views: 1386

Answers (1)

Krzysztof
Krzysztof

Reputation: 16140

You mentioned that you use Albahari MySQL driver. If you look at generated SQL for second query you will find out, that Skip(2) invocation is not included there. I have output like this:

SELECT COUNT(*)
FROM (
SELECT t1.id
FROM (
    SELECT t2.id
    FROM event AS t2
    LIMIT 0, 5
    ) AS t1
) AS t0

Apparently Skip works only when followed by Take. It may be bug, but it may be by design because of how LIMIT clause in MySQL works.

I found a way to past it. For this code:

var b = Events.Select(s => s.Id).Take(5).Skip(2).Take(int.MaxValue).Count();

you will have:

SELECT COUNT(*)
FROM (
SELECT t1.id
FROM (
    SELECT t2.id
    FROM event AS t2
    LIMIT 0, 5
    ) AS t1
LIMIT 2, 2147483647
) AS t0

Upvotes: 3

Related Questions