Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use OrderByDescending twice in LINQ?

I have a products table like this:-

ProductID     ProductName     Price
   1            Milk           10
   2            Banana         20
   3            Apple          15
   1            Grapes         12
   2            Banana         25
   1             Milk          8

I want to find the products who have maximum price for each productId.

Sample Output:-

    ProductID     ProductName     Price
       1            Grapes          12
       2            Banana         25
       3            Apple          15

I have tried this query:-

List<Product> groups = products
    .GroupBy(p => p.ProductId)
    .Select(p => new Product
        {
            ProductId = p.Key,
            Name = p.OrderByDescending(o => o.Price).First().Name,
            Price = p.OrderByDescending(o => o.Price).First().Price,
        })
    .ToList();

This query is working fine, but my question is should i use OrderByDescending twice? I mean since i just want single item based on 1 property and suppose there are multiple other properties, so do i need to use same logic again and again?

Edit: Pardon me forgot to mention, Please Assume ProductName can be different, Please check updated tables.

like image 740
Coder23 Avatar asked Dec 12 '14 11:12

Coder23


People also ask

What is difference between OrderBy and ThenBy in LINQ?

The OrderBy() Method, first sort the elements of the sequence or collection in ascending order after that ThenBy() method is used to again sort the result of OrderBy() method in ascending order.

How do you use OrderBy and ThenBy in LINQ?

Use ThenBy() method after OrderBy to sort the collection on another field in ascending order. Linq will first sort the collection based on primary field which is specified by OrderBy method and then sort the resulted collection in ascending order again based on secondary field specified by ThenBy method.

What is the use of ThenBy in LINQ?

LINQ ThenBy Operator is used when we want to sort the elements in a collection by using multiple properties in ascending order. This operator must use after OrderBy or OrderByDescending operator.


2 Answers

No, you don't have to, you can just select First():

new Product
{
    ProductId = p.Key,
    Name = p.First().Name,
    Bar = p.First().Bar,
    Price = p.OrderByDescending(o => o.Price).First().Price,
}

This of course assumes all products with a given ProductId have the same Name and Bar.

If this isn't the case and you want to map all properties from the selected entity, create a code block in your Select():

.Select(p => 
{   
    var havingHighestPrice = p.OrderByDescending(o => o.Price).First()

    return new Product
    {
      ProductId = p.Key,
      Name = havingHighestPrice.Name,
      Bar = havingHighestPrice.Bar,
      Price = havingHighestPrice.Price,
    }
})
like image 171
CodeCaster Avatar answered Oct 12 '22 19:10

CodeCaster


You can use Linq query syntax to store local variables:

var groups = from p in products.GroupBy(x => x.ProductId)
             let first = p.OrderByDescending(o => o.Price).First()
             select new Product
             {
                 ProductId = p.Key,
                 Name = first.Name,
                 Price = first.Price,
             };

What's important is that it's safe to use in Entity Framework queries.

like image 33
Grx70 Avatar answered Oct 12 '22 21:10

Grx70