Pages

12/05/2013

Linq to Entities and Last (LastOrDefault)

Linq to Entities and Last (LastOrDefault)



It is my bad luck – every time that I need to show something the team manager, we receive the weirdest exceptions. Today was the LINQ to Entities does not recognize the method ‘XXXXX.LastOrDefault[XXXX]….’ method, and this method cannot be translated into a store expression.
the expression itself was pretty simply – querying by secondary index. When I changed the query to “FirstOrDefault” removed the run time exception, this made me think – FirstOrDefault can be converted to SQL pretty easy – SELECT  TOP 1. How would you translate “LastOrDefault” ?
The concept of first or last implies the usage of some kind of sorting mechanism. When you run regular select there is actually implicit “ORDER BY [PK]” (notice that the order be ASC or DESC, depending of the PK defenition, in general, assuming some kind of sort without explicitly requesting it from the server is probably bad practice) done by the server. this is because of the way the data itself is stored in the sql data table.
So how “Last” should be implemented? Last is actually the first from the end. But how do you define “the end”? lets say you users table which one is the last user? The last registrated user ( order by ID) ? the last registered AND verified user? the last user to log in ? the user with the last lex. name (order by name)?
Conclustion:
If you want to get the last object directly from the sql server (you can use  .ToList().LastOrDefalt() but this will return all the entries and then take the last one – pretty useless with big tables) is to preform OrderByDescending and then take the fist.  :)
Here is generic function that receives “where” expression and orderBy selector and returns the last entry  matching the criteria.
 protected T GetLastBy(Expression> where, Expression> orderBy)
        {       
            return WorkingSet.OrderByDescending(orderBy).FirstOrDefault(where);
        }

No comments: