4

There are many similar questions on SO, but I'm not seeing one that fits my circumstances...

I'm wondering why this doesn't work to sort an IEnumerable of Premise objects:

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

I'm passing in a valid p.property for the orderBy argument and "ascending" or "descending" for the sortOrder argument

And if I can't 'dynamicize' my LINQ in a limited fashion like this, what alternative is there beside a big ugly Switch statement or something like that?

Many thanks for your time.

P.K
  • 17,429
  • 11
  • 40
  • 51
theog
  • 1,044
  • 2
  • 19
  • 32

4 Answers4

2

I think you're combining query notation, and dot notation. For this, try sticking to just dot notation:

sortedPremiseList = premiseList
           .OrderBy(p => string.Format("{0} {1}", p.orderBy, p.sortOrder));
Adam Rackis
  • 79,454
  • 49
  • 255
  • 377
1

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

Okay. I like a 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 the way you wrote it doesn't work, is that the LINQ expression is transformed into code at compile-time, and the string you are passing it is not evaluated until run-time.

cdiggins
  • 15,532
  • 6
  • 92
  • 95
1

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

sortedPremiseList = from p in premiseList
    orderby (string.Format("{0} {1}", p.orderBy, p.sortOrder))
    select p;
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
0

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);
        }
Sanchitos
  • 7,552
  • 4
  • 44
  • 49