2014-02-06 74 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)