是否可以通过反射来做到这一点? [复制]
Posted
技术标签:
【中文标题】是否可以通过反射来做到这一点? [复制]【英文标题】:Is it possible to do this with reflection? [duplicate] 【发布时间】:2012-10-22 05:30:29 【问题描述】:可能重复:Dynamic LINQ OrderBy
我有一个自定义排序选项列表,这些选项从客户端网格控件(如果您想知道的话是 KendoUI 网格)传递到服务器。这些排序选项具有作为字符串排序的属性。我编写了一个 switch 方法,它将检查排序对象的值并应用适当的 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);
这工作正常,但看起来很丑。我如何通过反射来做到这一点,这样我就不必为我想要使用的每种类型的实体编写自定义函数?如果无论实体是什么,我都可以只使用一个函数来执行此操作,那就太好了。
【问题讨论】:
我不知道反射会在这里做什么,但你可以用枚举替换你的字符串。 Dynamic LINQ OrderBy 【参考方案1】:您可以使用动态 LINQ。这是来自 Scott Gu 的blog post
。
【讨论】:
很好的解决方案。我不确定我更喜欢哪一个! 你让我的生活变得轻松多了。在存储库方法中执行此操作:foreach (var sort in kendoSorts) reports = reports.OrderBy(string.Format("0 1", sort.Field, sort.Dir));
foreach 允许它处理多个排序。【参考方案2】:
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]));
【讨论】:
不错!如果我将方法设为通用方法,我可以换掉Report
并将其用于我认为的任何集合。完美。
是的,效果应该很好。【参考方案3】:
使用反射,其中 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));
但是,反射相对较慢。其他解决方案可能更好。
【讨论】:
+1 用于回答我的确切问题,尽管反思实际上并不是我最终想要的 :)【参考方案4】:下面应该动态创建你想要的排序函数。
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 => x.ReportProperty 的形式创建一个 Func 委托,其中 ReportProperty 是 sort.Field 的值。
【讨论】:
以上是关于是否可以通过反射来做到这一点? [复制]的主要内容,如果未能解决你的问题,请参考以下文章