I want to be able to apply combo firstby / thenby sorting as follows:
allOrders().sort(s => s.ProductName, s => s.OrderDate)
So using this post as inspiration, I wrote this extension method, which compiles fine:
public static IQueryable<T> sort<T>(this IQueryable<T> entities, params
Expression<Func<T, object>>[] predicates) where T : class
{
var sorted = entities.OrderBy(predicates[0]);
for (int i = 1; i < predicates.Length; i++)
sorted = sorted.ThenBy(predicates[i]);
return sorted;
}
And I also tried this succint version, which also compiles:
public static IQueryable<T> sort<T>(this IQueryable<T> entities, params
Expression<Func<T, object>>[] predicates) where T : class
{
return predicates.Skip(1).Aggregate(
entities.OrderBy(predicates[0]),
(aggregate, currentPredicate) => aggregate.ThenBy(currentPredicate));
}
However if I try sort by a DateTime, I get this exception:
Unable to cast the type ‘System.DateTime’ to type ‘System.Object’. LINQ to Entities only supports casting EDM primitive or enumeration types.
What am I doing wrong? I am using EF5.
When you return a value type (such as
intorDateTime) from a lambda expression that returnsobject, the compiler generates aBox()call to turn the value type into a boxed object.The Entity Framework expression parser can’t handle this box expression.
The only solution is to pass a strongly-typed lambda expression that returns the value type.
To do that, you can mis-use collection initializers:
Collection initializers allow you to use type inference with an arbitrary number of different type parameters.