Reputation: 16949
I need to get the latest status for each product in a list. Except if the status is "Success" it should be returned instead of the latest status. I have the following query to get the latest item but not sure how to conditionally select items that have the Success status. E.g. in the table below ProductId 1 should return the SUCCESS row but not the CANCEL row which is the latest one. Any ideas how to solve this in a single linq query?
var query = list
.GroupBy(g => g.ProductId)
.Select(g => g.OrderByDescending(s => s.Created)
.FirstOrDefault())
.Select(s => new ProductDto
{
ProductId = s.ProductId,
Created = s.Created,
Status = s.Status
});
ProductId Created Status
1 2021-08-19 00:34:30 PREPARING
1 2021-08-19 00:35:30 VALIDATE
1 2021-08-19 00:36:30 SUCCESS
1 2021-08-19 00:37:30 CANCELLED
2 2021-08-19 00:36:30 PREPARING
2 2021-08-19 00:38:30 VALIDATE
Upvotes: 0
Views: 52
Reputation: 71308
You can sort first by whether it's a SUCCESS
row:
.Select(g => g.OrderBy(s => s.Status == "SUCCESS" ? 0 : 1)
.ThenByDescending(s => s.Created)
.FirstOrDefault())
This causes all SUCCESS
rows to come first, sorted by date, then the other rows, also sorted by date.
The intermediate sort (before FirstOrDefault
) is effectively:
ProductId Created Status
1 2021-08-19 00:36:30 SUCCESS
1 2021-08-19 00:37:30 CANCELLED
1 2021-08-19 00:35:30 VALIDATE
1 2021-08-19 00:34:30 PREPARING
2 2021-08-19 00:38:30 VALIDATE
2 2021-08-19 00:36:30 PREPARING
Upvotes: 1