2014-02-06 73 views
2

我在我的应用程序中进行排序,如下所示。动态按lambda表达式排序

public IQueryable<Users> SelectAll(string sSortExpression, string sSortOrder) 
{ 
    if (sSortOrder == "asc") 
    { 
     switch (sSortExpression) 
     { 
      case "FirstName": 
       return UsersRepository.Entities.OrderBy(x => x.FirstName); 
      case "LastName": 
       return UsersRepository.Entities.OrderBy(x => x.LastName); 
      default: 
       return UsersRepository.Entities.OrderBy(x => x.Id); 
     } 
    } 
    else 
    { 
     switch (sSortExpression) 
     { 
      case "FirstName": 
       return UsersRepository.Entities.OrderByDescending(x => x.FirstName); 
      case "LastName": 
       return UsersRepository.Entities.OrderByDescending(x => x.LastName); 
      default: 
       return UsersRepository.Entities.OrderByDescending(x => x.UserName); 
     } 
    } 
} 

现在它的罚款,但我必须到所有领域中Users表(大约30场)排序。 然后,该方法将是非常大的

我尝试使用反射像这样

public IQueryable<Users> SelectAll(string sSortExpression, string sSortOrder) 
{ 
    var _property = UsersRepository.GetType().GetProperties().Where(a => a.Name == sSortExpression); 
    if (sSortOrder == "asc") 
    { 
     return UsersRepository.Entities.OrderBy(x => _property); 
    } 
    else 
    { 
     return UsersRepository.Entities.OrderByDescending(x => _property); 
    } 
} 

但zhcon失败。

有没有更好的方法来做到这一点? 在此先感谢

回答

4

最简单的方法去:改变你的方法接受Expression而不是string

public IQueryable<Users> SelectAll<TProp>(Expression<Func<Users, TProp>> selector, string sSortOrder) 
{ 
    if (sSortOrder == "asc") 
    { 
     return UsersRepository.Entities.OrderBy(selector); 
    } 
    else 
    { 
     return UsersRepository.Entities.OrderByDescending(selector); 
    } 
} 

你可以称它为为:

SelectAll(x => x.LastName, "asc"); 

或者,如果你真的需要它的字符串,你必须使用System.Linq.Expressions.Expression类方法来生成表达式树:

public IQueryable<Users> SelectAll<TProp>(string sSortExpression, string sSortOrder) 
{ 
    var param = Expression.Parameter(typeof(Users)); 
    var propExpression = Expression.Lambda<Func<Users, TProp>>(Expression.Property(param, sSortExpression), param); 

    if (sSortOrder == "asc") 
    { 
     return UsersRepository.Entities.OrderBy(propExpression); 
    } 
    else 
    { 
     return UsersRepository.Entities.OrderByDescending(propExpression); 
    } 
} 

不过这需要对SelectAll调用指定的泛型类型参数:

var results = SelectAll<int>("Id", "asc"); 
+0

TProp:找不到类型命名空间 – Fool

+0

您是否更改了方法声明以包含''通用参数? – MarcinJuraszek

+0

它现在工作正常。谢谢 – Fool

3

您可以创建你的表达进行排序像

public IQueryable<Users> SelectAllByCompany(string sSortExpression, string sSortOrder) 
{ 
    var p = Expression.Parameter(typeof(Users),"u"); 
    var sortExpr = Expression.Lambda<Func<User,object>>(Expresion.Property(p,sSortExpression), p); 

    if (sSortOrder == "asc") 
    { 
     return UsersRepository.Entities.OrderBy(sortExpr); 
    } 
    else 
    { 
     return UsersRepository.Entities.OrderByDescending(sortExpr); 
    } 
} 
1

使用这种扩展方法: public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc) { 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); }

然后使用Users.OrderBy(sSortExpression,真要是降下来,如果上升FALSE)