可能重复:
Dynamic LINQ OrderBy
我有一个自定义排序选项列表,从客户端网格控件(KendoUI网格,如果你想知道)传递给服务器。这些排序选项具有按字符串排序的属性。我编写了一个switch方法,它将检查sort对象的值并应用适当的LINQ。
private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort)
{
switch (sort.Field)
{
case "name":
return sort.Dir == "asc" ? reports.OrderBy(x => x.Name) : reports.OrderByDescending(x => x.Name);
case "description":
return sort.Dir == "asc" ? reports.OrderBy(x => x.Description) : reports.OrderByDescending(x => x.Description);
default:
return sort.Dir == "asc" ? reports.OrderBy(x => x.Id) : reports.OrderByDescending(x => x.Id);
}
}
这很好但看起来很难看。我怎么能用反射这样做,这样我就不必为每个想要这样做的实体编写一个自定义函数?如果我可以只使用一个函数来执行此操作,那将是很好的,无论实体是什么。
答案 0 :(得分:2)
您可以使用Dynamic LINQ。这是来自Scott Gu的blog post
。
答案 1 :(得分:1)
Marc Gravell有一个名为FastMember的小型图书馆。您可以像这样使用它:
private IQueryable<Report> SortReports(IQueryable<Report> reports,KendoSort sort)
{
var accessor = TypeAccessor.Create(typeof(Report));
return sort.Dir == "asc" ?
reports.OrderBy(x => accessor[x,sort.Field]) :
reports.OrderByDescending(x => accessor[x,sort.Field]));
}
答案 2 :(得分:1)
使用Reflection,其中KendoSort.Property是Report属性的PropertyInfo,它返回排序所需的值。
private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort)
{
return sort.Dir == "asc" ? reports.OrderBy(x => sort.Property.GetValue(x)) : reports.OrderByDescending(x => sort.Property.GetValue(x));
}
然而,反思相对缓慢。其他解决方案可能更好。
答案 3 :(得分:1)
以下内容应该动态创建您想要的排序功能。
ParameterExpression pe = Expression.Parameter(typeof(Report), "x");
LambdaExpression le = Expression.Lambda(
Expression.PropertyOrField(pe, sort.Field),
new List<ParameterExpression>() {pe});
var leCompiled = (Func<Report, string>)le.Compile();
return sort.Dir == "asc" ? reports.OrderBy(leCompiled) : reports.OrderByDescending(leCompiled);
它以x =&gt;的形式创建一个Func委托。 x.ReportProperty,其中ReportProperty是sort.Field的值。