using System.Collections.Generic;
using System.Linq.Expressions;
public int Id { get; set; }
public string Name { get; set; }
public double BlowMe{get;set;}
public static class Program
public static void Main()
IOrderedQueryable<Entity> orderedQuery = GetOrderedQueryable();
ProcessOrderByInstructions(orderedQuery);
private static IOrderedQueryable<Entity> GetOrderedQueryable()
return Enumerable.Empty<Entity>().AsQueryable().OrderBy(e => e.Id).ThenBy(e => e.Name).ThenByDescending(e => e.BlowMe);
private static void ProcessOrderByInstructions<TEntity>(IOrderedQueryable<TEntity> orderedQuery)
var orderByClauses = GetOrderByClauses(orderedQuery.Expression);
foreach (var orderByClause in orderByClauses)
if(orderByClause != null)
Console.WriteLine(orderByClause);
public static IEnumerable<string> GetOrderByClauses(Expression expression, string? order = null)
if (expression is MethodCallExpression methodCall)
switch (methodCall.Method.Name)
case "ThenBy": order = "asc"; break;
case "OrderBy": order = "asc"; break;
case "ThenByDescending": order="dsc"; break;
case "OrderByDescending": order = "dsc"; break;
foreach (var arg in methodCall.Arguments)
if (arg is MethodCallExpression m)
foreach (var a in m.Arguments)
foreach(var oc in GetOrderByClauses(a, order))
yield return Render(a, order);
yield return Render(arg, order);
static string Render(Expression exp, string order)
if (exp is UnaryExpression u)
return u.Operand.ToString().Split(("=>"))[1].Split('.')[1] + ":" + order;