按lambda表达式动态排序

时间:2014-02-06 05:39:37

标签: c# entity-framework 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);
    }
}

但是发誓。

有没有更好的方法呢? 提前致谢

3 个答案:

答案 0 :(得分:5)

最简单的方法:将您的方法更改为接受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");

答案 1 :(得分: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);
    }
}

答案 2 :(得分:2)

使用此扩展方法: 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,如果降序则为true,如果升序则为false)