我想实现一个传递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);
}
实现动态排序与其有表达式树,还不如扩展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);
}
那这样写的话,EF是会在什么时候执行排序呢,比如如果要是我上面的方式的话应该是在数据库中排序吧,如果按照你的扩展方法是不是相当于先取后排序了,这样如果数据量大的话是不是很麻烦。
@邵明瑞: 和用表达式树的效果是一样的,你的函数签名可以这样写:
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();
}
}
Expression.Quote(orderByExpression) 这句没看懂,不用这个Quote来包装一下也可以正常运行,有说明区别吗?这这个Quote是什么作用?
作为方法泛型参数的一部分 IEnumerable<T> GetAllByPage<T,S>
调用的时候会感知到的。
那这个S是在哪定义的啊,如果我直接这样写的话会直接报错的 这个S 应该只是个泛型吧
@邵明瑞: 不用定义啊。。。你参数里有个Expression<Func<T,S>> 会感知出来的
@水牛刀刀: 你没理解我的意思啊,我的意思是说 我想把这个Expression<Func<T,S>>当作参数在其他的地方调用,但是这个我这种写法 直接vs就报错了啊,你粘贴一下看一下就知道了,谢谢
@邵明瑞: 如果要在其他地方(我想你是指这个方法之外,这个方法所在的类的内部)使用,你需要让S成为这个类的签名一部分,否则无法感知到的。你可以用一些内部类去包含这个泛型签名,具体做法可以参照Enumerable.OrderBy扩展方法的做法。
public async Task<IEnumerable<T>> GetSplit<s>(SearchBaseModel searchBaseModel, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc) 应该这样 在GetSplit后面有<s>
这种怎么传参呢