Skip to content

Instantly share code, notes, and snippets.

@aliozgur
Last active March 19, 2020 10:22
Show Gist options
  • Save aliozgur/3c4304d187eb9b47c0e75e96716c41bc to your computer and use it in GitHub Desktop.
Save aliozgur/3c4304d187eb9b47c0e75e96716c41bc to your computer and use it in GitHub Desktop.
Queryable OrderBy Extensions
public enum OrderDirection
{
Asc = 1,
Desc = -1
}
public class OrderDefinition
{
public string PropertyName { get; set; }
public OrderDirection OrderDir { get; set; } = OrderDirection.Asc;
}
public static class IQueryableOrderByExtensions
{
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
var lambda = (dynamic)ToLambda<T>(propertyName);
return Queryable.OrderBy(source, lambda);
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
{
var lambda = (dynamic)ToLambda<T>(propertyName);
return Queryable.ThenBy(source, lambda);
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName)
{
var lambda = (dynamic)ToLambda<T>(propertyName);
return Queryable.OrderByDescending(source, lambda);
}
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string propertyName)
{
var lambda = (dynamic)ToLambda<T>(propertyName);
return Queryable.ThenByDescending(source, lambda);
}
private static LambdaExpression ToLambda<T>(string propertyName)
{
var param = Expression.Parameter(typeof(T), "x");
Expression body = param;
body = Expression.PropertyOrField(body, propertyName);
return Expression.Lambda(body, param);
}
public static IOrderedQueryable<T> AppendOrderBy<T>(this IQueryable<T> query, string propertyName)
=> query.Expression.Type == typeof(IOrderedQueryable<T>)
? ((IOrderedQueryable<T>)query).ThenBy(propertyName)
: query.OrderBy(propertyName);
public static IOrderedQueryable<T> AppendOrderByDescending<T>(this IQueryable<T> query, string propertyName)
=> query.Expression.Type == typeof(IOrderedQueryable<T>)
? ((IOrderedQueryable<T>)query).ThenByDescending(propertyName)
: query.OrderByDescending(propertyName);
public static IOrderedQueryable<T> ApplyOrderBy<T>(this IQueryable<T> query, List<OrderDefinition> orderDefs)
{
IQueryable<T> result = query;
foreach(var orderDef in orderDefs)
{
switch(orderDef.OrderDir)
{
case OrderDirection.Asc:
result = result.AppendOrderBy(orderDef.PropertyName);
break;
case OrderDirection.Desc:
result = result.AppendOrderByDescending(orderDef.PropertyName);
break;
default:
break;
}
}
return result as IOrderedQueryable<T>;
}
}
using System;
public class Program
{
public static void Main()
{
var sampleData = Item.GenerateSampleData();
var query = sampleData.AsQueryable();
var orderDefs = new List<OrderDefinition> {
new OrderDefinition{PropertyName = nameof(Item.Id), OrderDir = OrderDirection.Desc }
,new OrderDefinition{PropertyName = nameof(Item.Name)}
,new OrderDefinition{PropertyName = nameof(Item.DateOfBirth), OrderDir = OrderDirection.Asc}
};
var ordered = query.ApplyOrderBy(orderDefs);
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public static List<Item> GenerateSampleData()
{
var result = new List<Item>();
foreach (var idx in Enumerable.Range(1, 100))
{
result.Add(new Item
{
Id = idx % 5,
Name = $"{Guid.NewGuid()}",
DateOfBirth = DateTime.Now.Subtract(TimeSpan.FromDays((idx % 10) * 365))
});
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment