3

I'm using Dynamic Linq and today I wanted to build a slightly more complex nested query:

"Composition
.Where(((ExpirationDate > DateTime.UtcNow.Date) && (ExpirationDate.Year != 9999)))
.OrderBy(\"ExpirationDate ASC\")
.Select(ExpirationDate)
.FirstOrDefault() == @0"

(the breaks are only there for readability in this post, not really there in code)

The query is held by a string variable and passed to this:

private static Func<IQueryable<T>, object, IQueryable<T>> CreateWhereExpression<T>(string whereClause) where T : class
{
     return (q, o) => q.Where(whereClause, o);
}

Which happily creates the Where expression. (note that whereClause contains the exact string above "Composition.Where....") But as soon as it's time to execute, it will complain:

No applicable aggregate method 'OrderBy' exists

So my question is, what am I doing wrong? How can I get the nested OrderBy to work?

Vincent
  • 1,459
  • 15
  • 37
  • Are you trying to parse `LINQ`? Dynamic LINQ doesn't support parsing own syntax. –  Sep 26 '14 at 06:42
  • Yes, I'm trying to get Dynamic Linq to parse the string as a Linq query. I also tried it with Linq syntax '.OrderBy(ExpirationDate)' but I got the same error. I'm trying to accomplish something similair to this: http://stackoverflow.com/questions/10314708/how-to-build-a-nested-query-with-the-dynamic-linq-library But with an orderby query. – Vincent Sep 26 '14 at 06:54

1 Answers1

3

By default DynamicLinq support a little functions for nested query to IEnumerable fields, all it defined in inteface IEnumerableSignatures like Where, Any, Count and etc, but don't have Orderby, Select or FirstOrDefault what you need.
So you can add it to this interface like

interface IEnumerableSignatures
{
    ....
    void OrderBy(object selector);
    void Select(object selector);
    void FirstOrDefault();
}

after that you need fix ParseAggregate method like this

Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
{
    ....
    if (signature.Name == "Min" || signature.Name == "Max" 
        || signature.Name == "OrderBy" || signature.Name == "Select" //add this for support OrderBy and Select that need two generic parameters
    )
    ....
}

at last next query will be work

"Composition
.Where((ExpirationDate > DateTime.UtcNow.Date) && (ExpirationDate.Year != 9999))
.OrderBy(ExpirationDate)
.Select(ExpirationDate)
.FirstOrDefault() == @0"
Grundy
  • 13,356
  • 3
  • 35
  • 55
  • +1. the version of DynamicLinq I was using vanished from Nuget and I had to pull in the base version, which is apparently missing this functionality. thanks! – John Nov 04 '16 at 13:20