简体   繁体   中英

Ordering not working in Entity Framework query

I'm currently battling a linq query for my application using Entity Framework (6.1.3)

The query is as follows:

var productPeriods = (from pp in ctx.ProductPeriods                                          
  where pp.IsActive && pp.Product.IsBuyBackForProduct == null && !pp.Product.ProductAddOns.Any() && pp.PowerRegionID == powerRegionId
  select new
  {
      ProductPeriod = pp,
      Price = pp.Prices
        .OrderByDescending(x => x.Created)
        .GroupBy(x => x.FirmID)
        .Select(pr => pr.FirstOrDefault())
        .OrderByDescending(x => x.ProductPrice)
        .FirstOrDefault()
  }).ToList();

The purpose of the query is to find the latest price from the prices collection of a product period, grouped by the firm ID and then select the best price of the latest prices from each firm.

This works perfectly in Linqpad, but the first OrderByDescending(x => x.Created) doesn't work when used in context of Entity Framework.

Does anyone knows why? And perhaps have a solution for it? :-)

Thanks in advance!

Update

Thanks for all replies. I've tried the following:

select new {
    ProductPeriod = p,  
    Price = p.Prices.GroupBy(x => x.FirmID).Select(pr => pr.OrderByDescending(x => x.Created).ThenByDescending(x => x.ProductPrice).FirstOrDefault())
}

But it seems like ThenByDescending(x => x.ProductPrice) gets ignored as well. The prices are not sorted correctly in the output. They're output like this:

Price: 0,22940, Created: 06-03-2015 10:15:09,
Price: 0,23150, Created: 06-03-2015 10:05:48
Price: 0,20040, Created: 06-03-2015 09:24:24

Update 2 (solution for now)

I came to the solution that the initial query just returns the latest prices from each firm. There's currently three firms, so the performance should be alright.

Later in my code, where I'm actually using the latest and best price, I simply do an .OrderByDescending(x => x.ProductPrice).FirstOrDefault() and check if it's not null.

Ie:

var productPeriods = (from pp in ctx.ProductPeriods
                      where pp.IsActive && pp.Product.IsBuyBackForProduct == null && !pp.Product.ProductAddOns.Any() && pp.PowerRegionID == powerRegionId
                      select new
                      {
                          ProductPeriod = pp,
                          Prices = pp.Prices.GroupBy(x => x.FirmID).Select(pr => pr.OrderByDescending(x => x.Created).FirstOrDefault())
                      }).ToList();

Later in my code:

var bestPriceOfToday = period.Prices.OrderByDescending(x => x.ProductPrice).FirstOrDefault()

The problem is the commands you are using. OrderBy and OrderByDescending do NOT add additional order by statements to the resulting query but instead they CREATE the order by statement and eliminate all orderby statements that existed before.

In order to use multiple orderby's you need to do the following:

  • OrderBy or OrderByDescending
  • ThenBy or ThenByDescending

the ThenBy statements can be used 1 or more times they just add additional order statements to the resulting query.

According to yours update, omnit select and type:

select new {
    ProductPeriod = p,  
    Price = p.Prices.GroupBy(x => x.FirmID)
        .OrderByDescending(x =>x.Created).ThenByDescending(x=>x.ProductPrice).FirstOrDefault()
}

That select was useless and could be the cause of problem

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