我希望能够按如下方式应用组合 firstby/thenby
排序:
allOrders().sort(s => s.ProductName, s => s.OrderDate)
所以使用 this post as inspiration ,我写了这个扩展方法,它编译得很好:
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;
}
而且我还尝试了这个简洁的版本,它也可以编译:
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));
}
但是,如果我尝试按 DateTime
排序,则会出现此异常:
Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
我做错了什么?我正在使用 EF5。
最佳答案
当您从返回 object
的 lambda 表达式返回值类型(例如 int
或 DateTime
)时,编译器会生成一个 Box()
调用将值类型转换为装箱对象。
Entity Framework 表达式解析器无法处理此框表达式。
唯一的解决方案是传递一个返回值类型的强类型 lambda 表达式。
为此,您可以滥用集合初始化程序:
public class OrderingCollection<TEntity> : IEnumerable {
public void Add<TProperty>(Expression<Func<TEntity, TProperty>>) {
...
}
}
public static IQueryable<T> Sort<T>(this IQueryable<T> entities,
OrderingCollection<T> o) where T : class {
...
}
q = q.Sort(new OrderingCollection { s => s.ProductName, s => s.OrderDate });
集合初始值设定项允许您对任意数量的不同类型参数使用类型推断。
关于c# - EF orderby/thenby 组合扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13056943/