c# - EF orderby/thenby 组合扩展方法

标签 c# linq entity-framework linq-to-entities linq-expressions

我希望能够按如下方式应用组合 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 表达式返回值类型(例如 intDateTime)时,编译器会生成一个 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/

相关文章:

c# - 使用NEST在ElasticSearch的IEnumerable属性上配置分析器的问题

c# - 如何格式化小数以截断除前两位以外的所有小数位零?

C# Linq Guid 匿名类型问题

asp.net - 使用 Linq 绑定(bind) Gridview 数据源 (asp.net)

c# - LINQ 到 XML : handling nodes that do not exist?

c# - 如果行存在则更新行否则使用 Entity Framework 插入逻辑

.net - 在多个服务之间共享 dbcontext 的最佳方式是什么?

c# - 通过继承创建一个惰性 DbContext 和一个急切 DbContext?

c# - 有效读取单个数据行

c# - HTTP 处理程序的相同 Asp.net 表单例份验证