I have a table called TicketHistory in which TicketId is a ForeignKey and I store records of update operations that are performed on ticket properties such as 'Status', 'Assignee', 'Priority', 'UpdateDate' etc. as my table data. So there is multiple rows with same TicketId value in the table.
What I am trying to do is writing Linq to fetch the List of history records belong to certain tickets that were at least once their Status updated as lets say "X". But as I said same update operation might have been performed on the same ticket multiple times and I want to retrieve only the latest one. So Basically only one record belong to a certain ticket (I am providing ticket Id(s)) which is the one that the ticket's status was updated as X last time.
I am using EntityFrameworkCore 3.1.4 and the Linq I wrote is as in below:
var histories = await _context.TicketHistories
.Include(i => i.Ticket).ThenInclude(t => t.Status)
.Include(n => n.Ticket).ThenInclude(h => h.Priority)
.Where(w => ticketIds.Any(a => a == w.TicketId) &&
w.Status.TicketStatusCode == "X" &&
w.Active &&
!w.Deleted)
.GroupBy(g => g.TicketId)
.OrderByDescending(o => o.Max(m => m.Created))
.Select(s => s.FirstOrDefault())
.ToListAsync();
Well, when I run the code above I get some error message as in title: "Lambda expression used inside Include is not valid."
Can you guys please help me to correct my linq or at least show me the way.
CodePudding user response:
It is known EF Core limitation, you cannot get items after grouping. Only Key
and aggregation result is supported. Note that starting from EF Core 6, your query will work.
You can use the following workaround, which mimics EF Core 6 query translation:
var dataQuery = _context.TicketHistories
.Include(i => i.Ticket).ThenInclude(t => t.Status)
.Include(n => n.Ticket)
.Where(w => ticketIds.Contains(w.TicketId) &&
w.Status.TicketStatusCode == "X" &&
w.Active &&
!w.Deleted);
var query =
from key in dataQuery.Select(d => new { d.TicketId }).Distinct()
from d in dataQuery.Where(d => d.TicketId == key.TicketId)
.OrderByDescending(d => d.Created)
.Take(1)
select d;
var histories = await query.ToListAsync();