Linq query on EFCore Sqlite does not work

c# entity-framework-core linq-to-entities sqlite


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

It looks 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?

1/28/2018 2:42:45 AM

Accepted Answer

Tested and reproduced in EF Core 2.0.1, SqlServer, hence this seems to be a current EF Core bug in Last / LastOrDefault general query translation.

The query

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();
1/28/2018 3:34:00 AM

Popular Answer

Call ToList on current before grabbing first and last?

//...code removed for brevity.

var current = set.OrderBy(row => row.Id).Take(20).ToList();

//...code removed for brevity.

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow