Reputation: 793
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
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