I'm using EFCore SQLite, when run a simple query with Linq, I notice that the query
Take().Last() does not return what is expected, sample code:
// There are more than 10000 rows in the table DbSet<DataEntry> set = ctx.Set<DataEntry>(); // this should return the first 20 rows var current = set.OrderBy(row => row.Id).Take(20); // first entry is right long tStart = current.First().Time; // This should have returned the last entry in the first 20 entries, but instead, it returned the last entry of the entire data set long tEnd = current.Last().Time; // so essentially it looks like this: set.Last().Time == set.Take(20).Last().Time
Last will return the last entry in the entire backing data set, no matter which query it is based on. How can I fix this?
Tested and reproduced in EF Core 2.0.1, SqlServer, hence this seems to be a current EF Core bug in
LastOrDefault general query translation.
var last = set.OrderBy(row => row.Id).Take(20).Last();
is translated as if it was
var last = set.OrderByDescending(row => row.Id).Take(20).First();
which of course is not equivalent and always returns the last record of the whole sequence (
Take has no effect).
I would suggest reporting it to the EF Core Issue Tracker.
Meanwhile, as a workaround you could use the ugly explicit equivalent:
var last = set.OrderBy(row => row.Id).Take(20) .OrderByDescending(row => row.Id).First();
current before grabbing first and last?
//...code removed for brevity. var current = set.OrderBy(row => row.Id).Take(20).ToList(); //...code removed for brevity.