linq2db / linq2db.EntityFrameworkCore

Bring power of Linq To DB to Entity Framework Core projects
MIT License
462 stars 38 forks source link

OrderBy clause is lost if it is placed before GroupBy #124

Closed Meigyoku-Thmn closed 3 years ago

Meigyoku-Thmn commented 3 years ago

This is a weird bug. With a query like this:

[Sql.Function("ANY_VALUE", ServerSideOnly = true, IsAggregate = true, ArgIndices = new[] { 0 })]
public static TItem AnyValue<TSource, TItem>(
    this IEnumerable<TSource> src, Expression<Func<TSource, TItem>> value)
{
    throw new InvalidOperationException();
}

LinqToDBForEFTools.Initialize();

var customers = (from c in db.Customer
                select new {
                  Id = c.Id,
                  CustomerName = c.Name + c.Id,
                })
                .OrderByDescending(c => c.CustomerName);

var grouped = (from c in customers 
               join p in db.Purchase on c.Id equals p.CustomerId
               group new { c, p } by c.Id into g
               select new {
                  CustomerId = g.Key,
                  CustomerName = g.AnyValue(e => e.c.CustomerName),
                  Count = g.Count(),
               })
               .ToLinqToDB()
               .ToArray();

then the generated sql doesn't have the order by clause:

SELECT
  `c_1`.`ID`,
  ANY_VALUE(Concat(`c_1`.`Name`, Cast(`c_1`.`ID` as CHAR(11)))),
  Count(*)
FROM
  `customer` `c_1`
          INNER JOIN `purchase` `p` ON `c_1`.`ID` = `p`.`CustomerID`
GROUP BY
  `c_1`.`ID`

There must be an ORDER BY clause at the end, or a nested query with ORDER BY clause.

sdanyliv commented 3 years ago

It is not a bug. Group By discards any ordering declared before,

Meigyoku-Thmn commented 3 years ago

Thanks. I also just realized that MySQL ignores ORDER BY clause in sub query so this will never work anyway.

sdanyliv commented 3 years ago

It's common sense. Grouping is complex algorithm which uses hashes, other techniques. And believe me, ordering after that is discarded anyway.