I have a SQLite table that contains every test result we\'ve run, and I\'m looking to write an entity framework query that returns only the most recent test result per project.
Try with a subquery instead of a grouping. Like this:
results = await _context.Results
.Include(x => x.Project)
.AsNoTracking()
.Where( r => r.Id == _context.Results.Where( rr => rr.ProjectId == r.ProjectID).Max( rr => rr.Id) )
.ToListAsync();
While this isn't portable, here's how this can be done using SQLite-compatable SQL and Entity Framework:
results = await _context.Results
.FromSqlRaw("SELECT Results.* FROM (SELECT Id, ProjectId, MAX(Updated) as Updated " +
"FROM Results GROUP BY ProjectId) as latest_results " +
"INNER JOIN Results ON Results.Id = latest_results.Id")
.Include(x => x.Project) //not required for question but useful
.OrderBy(x => x.Project.Name)
.AsNoTracking()
.ToListAsync();
If someone has a way to do this in pure LINQ/EF, but still perform the query server-side, I'll happily mark that as the answer, since this is dependent on the exact SQL dialect used.
Your method couldn't be translated to T-SQL, Linq to Entities couldn't recognize it. You can modify the code as below (adding AsEnumerable after AsNoTracking
):
.Include(x => x.Project)
.AsNoTracking()
.AsEnumerable()
With AsEnumerable
after data is loaded, any further operation is performed using Linq to Objects, on the data already in memory.