cResults
cResults

Reputation: 793

How to add SelectMany to an Expression Tree with Expression.Call

How do I achive the same result as:

var q = db.TableA.AsQueryable();
var q1 = Queryable.SelectMany(q, a => a.TableB, (a, t) => new { a = a, t = t });
var q2 = Queryable.SelectMany(q1, a=> a.a.TableC, (a, t) = new { a = a, t = t });

by creating an expression tree via Expression.Call:

MethodCallExpression returnCallExpression = Expression.Call(
     typeof(Queryable),
     "SelectMany",
     new Type[] ??????,
     query.Expression,
     a => a.TableB,
     (a, t) => new { a = a, t = t });

I'm researching the other overloads of Expression.Call to see if this can be achieved without declaring type.

My issue is that the number of SelectManys is determined at run-time so I can't just chain them. And each SelectMany changes the anonymous type of the IQueryable, so I'm having trouble getting around not knowing the type at compile-time.

Any ideas about how to apply n number of SelectMany to an IQueryable are greatly appreciated.

Upvotes: 1

Views: 1150

Answers (1)

Jonno
Jonno

Reputation: 1976

Do you actually have the lambda expressions "available" such as a => a.TableB or are they dynamic as well?

You could use something like this perhaps (based on this SO post):

public Type[] GetSelectManysAnonymousTypes<TSource, TCollection, TResult>(
        IQueryable<TSource> queryable,
        Expression<Func<TSource, IEnumerable<TCollection>>> collectionSelector,
        Expression<Func<TSource, TCollection, TResult>> resultSelector)
{
    return new [] {
        typeof(Expression<Func<TSource, IEnumerable<TCollection>>>),
        typeof(Expression<Func<TSource, TCollection, TResult>>) };
}

Or something a bit more complicated could give you back the Type[] together with the Expression[] i.e. array of expressions - ready to call Expression.Call().

I think the problem you are facing though is, forgetting anonymous types, you don't know what the collectionSelector parameter lambda looks like if you really have a dynamic, unknown number of SelectMany()'s chained together. Or I may be missing something...

Upvotes: 1

Related Questions