Search code examples
entity-frameworklinq-to-sqllambdaexpression-treesiqueryable

Finding the appropriate return type for linq to SQL generic functions


I'm trying to build an extension method to IQueryable which accepts a sort direction as an argument. I want to be able to apply this method to SQL server queries with EF. Here is what I have so far:

public static class QueryableExtensions
{
    public static IOrderedQueryable<T> ApplyOrdering<T>(this IQueryable<T> source, Expression<Func<T, Object>> lambda, bool ascending)
    {
        return ascending ? source.OrderBy(lambda) : source.OrderByDescending(lambda);
    }
}

I have the following driver code:

    [Table("TestTable")]
public partial class TestTable
{
    [Key]
    public int IntVal { get; set; }
}

public partial class Model1 : DbContext
{
    public Model1()
        : base("name=Model1")
    {
    }

    public virtual DbSet<TestTable> TestTables { get; set; }
}

class Program
{
    private static void Main(string[] args)
    {
        var context = new Model1();
        var baseQuery = from entity in context.TestTables 
                            select entity;

        var sortedByInt = baseQuery.ApplyOrdering(x => x.IntVal, true).ToList();
    }
}

However, running this code leads to the following error:

Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.

Is there a work around? I suspect I need an alternative return type to the Expression.


Solution

  • Try:

    public static class QueryableExtensions
    {
        public static IOrderedQueryable<T> ApplyOrdering<T, TProp>(this IQueryable<T> source, Expression<Func<T, TProp>> lambda, bool ascending)
        {
             return ascending ? source.OrderBy(lambda) : source.OrderByDescending(lambda);
         }
    }