简体   繁体   中英

How to get a list of only the most recent data belonging an Entity from a table with multiple data belonging the same Entity using LINQ

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.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM