none
Dynamic LINQ OrderBy using String Names

    Question

  • Hi,

    I need to create a dynamic order by expression from a field name. I try to perform something like explained at this post:

    http://www.singingeels.com/Articles/Self_Sorting_GridView_with_LINQ_Expression_Trees.aspx

    That is:

     public Expression<Func<KEntity, object>> SortExpression
     {
      get
      {
      if (string.IsNullOrEmpty(this.SortFieldName))
      {
       return null;
      }
      else
      {
       ParameterExpression pe = Expression.Parameter(typeof(KEntity), "p");
       var property = Expression.Property(pe, this.SortFieldName);
       Expression expression = Expression.Convert(property, typeof(object));
       return Expression.Lambda<Func<KEntity, object>>(expression, pe);
      }
      }
     }
    

    But when I try to sort a DateTime field I still have this exception:

    Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.

    I know this could be solved using a generic returned type instead an object, but I don't know how to pass this type dynamically.

    Any ideas about how to solve this problem?

    Thanks in advance,

    JAReyes.


    Please remember to Vote & "Mark As Answer" if this post is helpful to you.
    Por favor, recuerda Votar y "Marcar como respuesta" si la solucion de esta pregunta te ha sido útil.
    Monday, February 14, 2011 10:33 AM

Answers


  • public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string memberName)
    {
     ParameterExpression[] typeParams = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };
    
     System.Reflection.PropertyInfo pi = typeof(T).GetProperty(memberName);
    
     return (IOrderedQueryable<T>)query.Provider.CreateQuery(
     Expression.Call(
      typeof(Queryable),
      "OrderBy",
      new Type[] { typeof(T), pi.PropertyType },
      query.Expression,
      Expression.Lambda(Expression.Property(typeParams[0], pi), typeParams))
     );
    }


     
       Cool tools for Linq-to-SQL and Entity Framework 4:
     huagati.com/dbmltools - Visual Studio add-in with loads of new features for the Entity Framework and Linq-to-SQL designers
     huagati.com/L2SProfiler - Runtime SQL query profiler for Linq-to-SQL and Entity Framework v4
    Monday, February 14, 2011 11:39 AM
  • Hi Kristofer,

    I will prefer a function returning an expression like you propose first:

    public static Expression<Func<T, TKey>> OrderExpression<T, TKey>(string memberName)
    {
        ParameterExpression[] typeParams = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };

        Expression<Func<T, TKey>> orderByExpression
            = (Expression<Func<T, TKey>>)Expression.Lambda(
                Expression.Property(typeParams[0], memberName),
                typeParams
              );

        return orderByExpression;
    }

    I know I can use generics, but I can't know this type because it is dynamic.

    If I perform an OrderBy extension, I will need to extend also OrderByDescending, ThenBy and ThenByDescending methods. Besides perform changes at my repositories...


    Please remember to Vote & "Mark As Answer" if this post is helpful to you.
    Por favor, recuerda Votar y "Marcar como respuesta" si la solucion de esta pregunta te ha sido útil.
    Monday, February 14, 2011 1:25 PM

All replies


  • public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string memberName)
    {
     ParameterExpression[] typeParams = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };
    
     System.Reflection.PropertyInfo pi = typeof(T).GetProperty(memberName);
    
     return (IOrderedQueryable<T>)query.Provider.CreateQuery(
     Expression.Call(
      typeof(Queryable),
      "OrderBy",
      new Type[] { typeof(T), pi.PropertyType },
      query.Expression,
      Expression.Lambda(Expression.Property(typeParams[0], pi), typeParams))
     );
    }


     
       Cool tools for Linq-to-SQL and Entity Framework 4:
     huagati.com/dbmltools - Visual Studio add-in with loads of new features for the Entity Framework and Linq-to-SQL designers
     huagati.com/L2SProfiler - Runtime SQL query profiler for Linq-to-SQL and Entity Framework v4
    Monday, February 14, 2011 11:39 AM
  • Hi Kristofer,

    I will prefer a function returning an expression like you propose first:

    public static Expression<Func<T, TKey>> OrderExpression<T, TKey>(string memberName)
    {
        ParameterExpression[] typeParams = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };

        Expression<Func<T, TKey>> orderByExpression
            = (Expression<Func<T, TKey>>)Expression.Lambda(
                Expression.Property(typeParams[0], memberName),
                typeParams
              );

        return orderByExpression;
    }

    I know I can use generics, but I can't know this type because it is dynamic.

    If I perform an OrderBy extension, I will need to extend also OrderByDescending, ThenBy and ThenByDescending methods. Besides perform changes at my repositories...


    Please remember to Vote & "Mark As Answer" if this post is helpful to you.
    Por favor, recuerda Votar y "Marcar como respuesta" si la solucion de esta pregunta te ha sido útil.
    Monday, February 14, 2011 1:25 PM