首页 新闻 会员 周边

Expression<Func<T, S>> 动态排序类型

0
悬赏园豆:20 [已解决问题] 解决于 2013-10-30 15:53

我想实现一个传递lambda表达式来实现排序,Expression<Func<T, S>>当作参数来传递,请问如何实现,Expression<Func<T, object>>如果这样写的话报转换错误,如果是Expression<Func<T, S>> 那这个S要在哪定义呢,谢谢大家。

问题补充:

    public interface IRepository<T> where T : class{

  IEnumerable<T> GetAllByPage(int page, int pageSize, Expression<Func<T, bool>> where, Expression<Func<T, S>> orderByExpression, bool IsDESC);

}

邵明瑞的主页 邵明瑞 | 初学一级 | 园豆:105
提问于:2013-04-24 17:31
< >
分享
最佳答案
0

实现动态排序与其有表达式树,还不如扩展IQueryable

public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty,
bool desc) where TEntity : class
{
  string command = desc ? "OrderByDescending" : "OrderBy";

  var type = typeof(TEntity);
  var property = type.GetProperty(orderByProperty);
  var parameter = Expression.Parameter(type, "p");
  var propertyAccess = Expression.MakeMemberAccess(parameter, property);
  var orderByExpression = Expression.Lambda(propertyAccess, parameter);
  var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type,           property.PropertyType },source.Expression, Expression.Quote(orderByExpression));

  return source.Provider.CreateQuery<TEntity>(resultExpression);
}

收获园豆:8
settan | 初学一级 |园豆:154 | 2013-05-16 19:36

那这样写的话,EF是会在什么时候执行排序呢,比如如果要是我上面的方式的话应该是在数据库中排序吧,如果按照你的扩展方法是不是相当于先取后排序了,这样如果数据量大的话是不是很麻烦。

邵明瑞 | 园豆:105 (初学一级) | 2013-05-17 08:48

@邵明瑞: 和用表达式树的效果是一样的,你的函数签名可以这样写:

public interface IRepository<T> where T : class{

  IEnumerable<T> GetAllByPage(int page, int pageSize, Expression<Func<T, bool>> where, string orderByProperty, bool IsDESC)

{

  IQueryable<T> query = .....;

  query = query.Where(where);

  query = query.OrderBy(orderByProperty,IsDESC);

  query = query.Skip((page-1)*pageSize).Take(pageSize);

  return query. AsEnumerable();

}

}

settan | 园豆:154 (初学一级) | 2013-05-17 15:30

Expression.Quote(orderByExpression) 这句没看懂,不用这个Quote来包装一下也可以正常运行,有说明区别吗?这这个Quote是什么作用?

变形精怪 | 园豆:5 (初学一级) | 2014-06-29 21:15
其他回答(3)
0

作为方法泛型参数的一部分 IEnumerable<T> GetAllByPage<T,S>

调用的时候会感知到的。

收获园豆:6
水牛刀刀 | 园豆:6350 (大侠五级) | 2013-04-24 17:54

那这个S是在哪定义的啊,如果我直接这样写的话会直接报错的 这个S  应该只是个泛型吧

支持(0) 反对(0) 邵明瑞 | 园豆:105 (初学一级) | 2013-04-25 08:32

@邵明瑞: 不用定义啊。。。你参数里有个Expression<Func<T,S>> 会感知出来的

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2013-04-25 09:57

@水牛刀刀: 你没理解我的意思啊,我的意思是说 我想把这个Expression<Func<T,S>>当作参数在其他的地方调用,但是这个我这种写法 直接vs就报错了啊,你粘贴一下看一下就知道了,谢谢

支持(0) 反对(0) 邵明瑞 | 园豆:105 (初学一级) | 2013-04-25 10:29

@邵明瑞: 如果要在其他地方(我想你是指这个方法之外,这个方法所在的类的内部)使用,你需要让S成为这个类的签名一部分,否则无法感知到的。你可以用一些内部类去包含这个泛型签名,具体做法可以参照Enumerable.OrderBy扩展方法的做法。

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2013-04-25 12:00
0

public async Task<IEnumerable<T>> GetSplit<s>(SearchBaseModel searchBaseModel, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc) 应该这样 在GetSplit后面有<s>

星炎123 | 园豆:202 (菜鸟二级) | 2019-07-31 11:21
0

这种怎么传参呢

RookieMx | 园豆:206 (菜鸟二级) | 2021-05-20 15:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册