Home > Software engineering >  EF Behavior of Last and LastOrDefault
EF Behavior of Last and LastOrDefault

Time:10-21

Recently I was enhancing my knowledge with EF and to stay up to date I just went for the hole path on Pluralsight. Whith that in mind I checked out a few courses by Julie Lerman which is by the way a great teacher.

During the course there was a short recap on some of the built in functionalites of linq and how it interprets it into the query. I just wondered if this will be updated with a feature release and wonder why this is behaving like that.

From Entity Framework Core: Getting Started courese Quote: "Last methods require query to have an order by method otherwise will return full set then pick last in memory."

Thanks

CodePudding user response:

First/Last methods both should always have an Order By clause to try and ensure the results are repeatable. There is really no good reason to use a Last method in an EF linq expression, just reverse the ordering and use a First method. The only possible reason would be situations where you want the First and Last item from a query expression.

You can learn a lot about what EF is doing by running a profiler and inspecting the generated SQL. Two reasons came to mind why EF would require an Order By clause to do the Last operation. The first was that SQL would typically approach a LAST type scenario using something like a MAX(...) expression which would require a column or columns to work out. The second was that it could possibly look to reverse the existing order by conditions. I thought it would be be first option, but looking at the generated SQL it is actually the second.

var test = context.Parents.OrderBy(x => x.Name).First();

SELECT TOP(1) [p].[ParentId], [p].[MasterParentId], [p].[Name]
FROM [Parents] AS [p]
ORDER BY [p].[Name] 
go

var test = context.Parents.OrderBy(x => x.Name).Last();

SELECT TOP(1) [p].[ParentId], [p].[MasterParentId], [p].[Name]
FROM [Parents] AS [p]
ORDER BY [p].[Name] DESC
go

The MAX approach that you might use with SQL Server may be provider dependent and it might be problematic when working with multiple Order By expressions.

It is worth noting that EF's ability to support Linq methods is provider implementation specific so not all operations are supported by all providers or all versions of EF. For example, the Last/LastOrDefault methods are not supported in EF6, they expect you to reverse the Order By conditions and use First*.

The reason Last methods would need an OrderBy clause to avoid performing the operation in memory would likely be that EF would generate a query that compared a value against a MAX(...) operation. Without that, it cannot generate an SQL statement to get a last row and would have to load everything to enumerate over.

  • Related