0

I am trying to convert this Func to use string values using linq.dynamic.

Currently I have

Func<IQueryable<Customer>, IOrderedQueryable<Customer>> orderBy = o => o.OrderBy(c => c.Postcode);

But I want to do

string sortItem = "customer";
string order = "ASC"
Func<IQueryable<Customer>, IOrderedQueryable<Customer>> orderBy = o => o.OrderBy(sortItem + " " + order);

I am using the Linq.Dynamic library but I am unable to get it to work with the function.

Any help...

James Andrew Smith
  • 1,516
  • 2
  • 23
  • 43
  • Is this LINQ to SQL or EF? If the later, consider the builder methods of ObjectQuery rather than pulling in the dynamic library. – Jim Wooley Feb 20 '14 at 17:26
  • This is EF. I was able to do this before when querying the dbcontext but now with using a generic repository things are more complicated. – James Andrew Smith Feb 20 '14 at 18:15
  • possible duplicate of [Dynamic LINQ OrderBy on IEnumerable](http://stackoverflow.com/questions/41244/dynamic-linq-orderby-on-ienumerablet) – Gert Arnold Feb 20 '14 at 18:18

2 Answers2

0

Like the other answer suggests, this may not be possible. However, I wanted to post some code which I wrote recently to do something similar:

// single column sorting support
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<LegalComplianceDatatable, string> orderingFunction = (c => sortColumnIndex == 0 ? c.HomeCountry :
                                                    sortColumnIndex == 1 ? c.HostCountry :
                                                    sortColumnIndex == 2 ? c.YearOneRate :
                                                    sortColumnIndex == 3 ? c.YearOtherRate :
                                                    sortColumnIndex == 4 ? c.RateType :
                                                    c.HostCountry);

if (Request["sSortDir_0"] == "desc")
{
    filteredResults = filteredResults.OrderByDescending(orderingFunction);
}
else
{
    filteredResults = filteredResults.OrderBy(orderingFunction);
}
user1477388
  • 20,790
  • 32
  • 144
  • 264
0

I haven't used Linq.Dynamic but you can achieve this if you are comfortable building your own expression tree. For example:

public static class IQueryableExtension
{
    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
    {

        var memberProp = typeof(T).GetProperty(propertyName);
        var method = typeof(IQueryableExtension).GetMethod("OrderByInternal")
                                   .MakeGenericMethod(typeof(T), memberProp.PropertyType);

        return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
    }

    public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
    {
        if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();

        var thisArg = Expression.Parameter(typeof(T));
        var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);

        return query.OrderBy(lamba);

    }
}

And you can use this like:

IQueryable<Customer> query; // Some query
query = query.OrderBy("Name"); // Will return an IOrderedQueryable<Customer>

This is the logic for ascending sort, without checking (you will need to make sure the property exists, and so on) and some things can be optimized (the reflected method invocation for example). It should get you started.

Simon Belanger
  • 14,752
  • 3
  • 41
  • 35