使用列名作为参数

时间:2016-05-16 10:28:52

标签: c# linq lambda asp.net-mvc-5 pagedlist

我必须实现排序。虽然我想通过不对下面的x.SlNo模型进行硬编码来实现这一点。

public ActionResult Index(string sortOrder, string sortDirection, int? itemsPerPage, int? page, string SearchString)
{                                              
    IPagedList<TransferBenefits> entityList = null;                                 
    sortOrder = String.IsNullOrEmpty(sortOrder) ? "SlNo" : sortOrder;       

    var propertyInfo = typeof(TransferBenefits).GetProperty(sortOrder);
    var selectList = db.transferBenefits.OrderBy(x => propertyInfo.GetValue(x, null));
    //selectList = db.transferBenefits.OrderBy(x => x.SlNo); --uncommenting this works.
    entityList = selectList.ToPagedList(pageNumber: page ?? 1, pageSize: itemsPerPage ?? 10);

    return View(entityList) 
}

我收到此错误,而取消注释代码运行正常。

mscorlib.dll中发生了'System.NotSupportedException'类型的异常,但未在用户代码中处理

其他信息:LINQ to Entities无法识别方法'System.Object GetValue(System.Object, System.Object[])'方法,并且此方法无法转换为商店表达式。

1 个答案:

答案 0 :(得分:0)

您可以使用Expression构建参数。

public static class IQueryableExtensions
{
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortName, string sortOrder)
    {
        if (string.IsNullOrEmpty(sortName)) return query;
        var retQuery = query;
        var propGroup = sortName.Split(',');

        for (int k = 0; k < propGroup.Length; k++)
        {
            var typeOfProp = typeof(T);
            var sortField = propGroup[k];
            var currentOrder = GetOrderMethod(sortOrder, k);
            var param = Expression.Parameter(typeof(T), "o");
            var props = sortField.Split('.');
            Expression propertyAccess = param;
            var i = 0;
            do
            {
                var property = ReflectionTypePropertyCache<T>.GetProperty(props[i]);
                if (property == null) throw new Exception("property not found :" + sortName);
                typeOfProp = property.PropertyType;
                propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
                i++;
            } while (i < props.Length);

            var orderByExp = Expression.Lambda(propertyAccess, param);
            var resultExp = Expression.Call(typeof(Queryable),
                    currentOrder,
                    new[] { typeof(T), typeOfProp },
                    retQuery.Expression,
                    Expression.Quote(orderByExp));
            retQuery = retQuery.Provider.CreateQuery<T>(resultExp);
        }
        return retQuery;
    }

    private static string GetOrderMethod(string sortOrder, int index)
    {
        const string ASC = "OrderBy";
        const string DESC = "OrderByDescending";
        const string THENASC = "ThenBy";
        const string THENDESC = "ThenByDescending";
        string AscVar, DescVar;
        if (index == 0)
        {
            AscVar = ASC;
            DescVar = DESC;
        }
        else
        {
            AscVar = THENASC;
            DescVar = THENDESC;
        }

        if (string.IsNullOrEmpty(sortOrder)) return AscVar;
        var orderArr = sortOrder.Split(',');
        if (index >= orderArr.Length) return AscVar;
        if (orderArr[index].ToLower() == "desc") return DescVar;
        return AscVar;
    }
}

您可以将其用作:

var selectList = db.transferBenefits.OrderBy(sortOrder,"");