Reputation: 379
is it possible to construct MethodCallExpression (by using Expression.Call), when this call is NESTED? so, in design time, the actual sequnce (IQueryable or IEnumerable) which the call should be run against, is unknown?
Example:
let's say this is the query:
var result = data.GroupBy(x => x.Name).Select(grouping => grouping.OrderByDescending(x => x.Date).Take(1).FirstOrDefault()).ToList();
when data is a list of objects contains:Name,Date properties.
How do i constructs this query block:
grouping => grouping.OrderByDescending(x => x.Date)
using Expression.call?
thanks
My Answer:
I managed to sort this out.
Aducci gave me the direction, thnks!
the key was to use ParameterExpression and not an actual collection instance.
From here, the sulotion is just around the corner: complie the Expression>, and call the compiled result with the actual collection.
this was very helpful: MethodCallExpression -> compiled expression
and also : link
i'm adding my final code:
Expression<Func<Data,DateTime>> lmbd = x => x.Date;
ParameterExpression par = Expression.Parameter(typeof(IQueryable<Data>),"pname");
ParameterExpression[] parameters = new ParameterExpression[] {par};
MethodCallExpression method = Expression.Call(typeof(Queryable),"OrderBy",new Type[]{typeof(Data),typeof(DateTime)},par, lmbd);
var lambaExpression = Expression.Lambda<Func<IQueryable<Data>, IQueryable<Data>>>(method, par);
var compiled = lambaExpression.Compile();
Thank you all!
Upvotes: 0
Views: 587
Reputation: 26694
I asked a similar question which can be found here
ParameterExpression innerParameter = Expression.Parameter(typeof(GROUPING), "x");
Expression innerExpression = Expression.Lambda<Func<DATA, object>>(Expression.Property(innerParameter, "Date"),
innerParameter);
ParameterExpression parameter = Expression.Parameter(typeof(DATA), "grouping");
Expression call = Expression.Call(typeof(Enumerable),
"OrderByDescending",
new type[] { typeof(DATA) },
parameter,
innerExpression);
Upvotes: 1