Can this be done with reflection?

Possible duplicate:
Dynamic LINQ OrderBy

I have a list of custom sorting options that are passed to the server using client-side network management (KendoUI grid, if you're interested). These sorting options have the ability to sort as a string. I wrote a switch method that will check the values ​​of the sort object and apply the appropriate 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); } } 

It works great, but it seems so ugly. How can I do this with reflection, so that I don’t need to write a custom function for each type of entity with which I want to do this? It would be nice if I could have only one function that did this no matter what the entity is.

+4
source share
4 answers

You can use Dynamic LINQ. Here's a blog post about it from Scott Gu.

+2
source

Mark Gravel has a small library called FastMember . You can use it as follows:

 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])); } 
+1
source

Using Reflection, where KendoSort.Property is the PropertyInfo of the Report property, which returns the value needed for sorting.

 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)); } 

But then the reflection is relatively slow. Other solutions are probably better.

+1
source

The following is to create the sort function you want dynamically.

 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); 

It creates a Func delegate in the form x => x.ReportProperty, where ReportProperty is the value of sort.Field.

+1
source

Source: https://habr.com/ru/post/1441193/


All Articles