Sort IEnumerable using LINQ

There are many similar questions on SO, but I don’t see what fits my circumstances ...

I am wondering why this does not work for sorting IEnumerable objects of Premise objects:

sortedPremiseList = from p in premiseList orderby (string.Format("{0} {1}", orderBy, sortOrder)) select p; 

I pass a valid p.property for the orderBy argument and up or down for the sortOrder argument

And if I can't β€œdynamize” my LINQ in a limited way, like this, which alternative exists next to the big ugly Switch statement or something like that?

Thanks so much for your time.

+4
source share
4 answers

I think you are combining query notation and dot notation. To do this, try to stick to point notation only:

 sortedPremiseList = premiseList .OrderBy(p => string.Format("{0} {1}", p.orderBy, p.sortOrder)); 
+2
source

I think you need to reference p inside your call to string.Format() , for example:

 sortedPremiseList = from p in premiseList orderby (string.Format("{0} {1}", p.orderBy, p.sortOrder)) select p; 
+1
source

I think I understand what you are asking for here. You want to build a LINQ query from string arguments

Good. I like the challenge.

 IComparable GetPropValue( object src, string propName ) { return (IComparable)src.GetType( ).GetProperty( propName ).GetValue( src, null ); } IEnumerable<Premise> SortMyPremises(IEnumerable<Premise> premises, string propertyName, string ascendingOrDescending) { return ascendingOrDescending = "ascending" ? premises.OrderBy(p => GetPropValue(p, propertyName)) : premises.OrderByDescending(p => GetPropValue(p, propertyName)); } 

The reason you wrote it does not work is because the LINQ expression is converted to code at compile time, and the line you pass in is not evaluated until runtime.

+1
source

This worked for me:

 public static IEnumerable<TEntity> OrderBy<TEntity>(this IEnumerable<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.AsQueryable().Expression, Expression.Quote(orderByExpression)); return source.AsQueryable().Provider.CreateQuery<TEntity>(resultExpression); } 
0
source

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


All Articles