问题
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?
回答1:
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"
来源:https://stackoverflow.com/questions/26053488/how-does-nesting-an-orderby-in-a-dynamic-linq-query-work