如何使用Expression.Call将SelectMany添加到表达式树中

本文关键字:表达式 添加 SelectMany 何使用 Expression Call | 更新日期: 2023-09-27 18:19:59

如何获得与相同的结果

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 });

通过expression创建表达式树。调用:

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

我正在研究Expression的其他重载。调用看看是否可以在不声明类型的情况下实现这一点。

我的问题是SelectMany的数量是在运行时确定的,所以我不能只是将它们链接起来。每个SelectMany都会更改IQueryable的匿名类型,所以我很难在编译时不知道类型。

任何关于如何将n个SelectMany应用于IQueryable的想法都将不胜感激。

如何使用Expression.Call将SelectMany添加到表达式树中

您实际上有"可用"的lambda表达式(如a => a.TableB)吗?还是它们也是动态的?

你也许可以使用这样的东西(基于这篇SO帖子):

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>>) };
}

或者,更复杂的东西可以将Type[]Expression[]一起返回,即表达式数组-准备调用Expression.call().

不过,我认为您面临的问题是,忘记了匿名类型,如果您真的有一个动态的、未知数量的SelectMany()链接在一起,您就不知道collectionSelector参数lambda是什么样子的。或者我可能错过了什么。。。